Ein Upload, der an einer Größengrenze scheitert, ist ein Limit — siehe 413 Anfrage zu groß. Ein Upload, der mittendrin scheitert, bei keiner festen Größe, und dessen Verbindung einfach abreißt, ist ein Timeout irgendwo auf dem Weg.

Die Timeouts, die Sie erhöhen — alle davon

# nginx
client_body_timeout 300s;
client_max_body_size 512M;
send_timeout 300s;
fastcgi_read_timeout 300s;
proxy_read_timeout 300s;
; php
max_execution_time = 300
max_input_time = 300      ; the one that is forgotten - it covers the UPLOAD itself

max_input_time begrenzt, wie lange PHP mit dem Empfang der Anfrage verbringt. Es ist von max_execution_time getrennt, standardmäßig niedrig und genau das, was einen langsamen Upload vom Handy abwürgt.

Platte und temporärer Speicher

df -h /tmp /var/lib/php/tmp
grep upload_tmp_dir /etc/php/8.3/fpm/php.ini

Ein Upload wird zuerst in eine temporäre Datei geschrieben. Läuft dieses Dateisystem voll, scheitert der Schreibvorgang mitten in der Übertragung, und die Verbindung fällt ohne Meldung irgendwo aus.

Sehen Sie nach, was aufgezeichnet wurde

sudo tail -50 /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm -n 50 --no-pager

client intended to send too large body ist die Größengrenze. timed out und upstream prematurely closed sind die Timeouts von oben. Gar nichts heißt meist, dass Browser oder Proxy vor dem Server aufgegeben haben.

Hinter Cloudflare hat der Proxy in den kleineren Tarifen eine eigene Upload-Obergrenze, und die gilt, egal was Sie lokal einstellen. Laden Sie auf eine Subdomain hoch, die den Proxy umgeht, oder laden Sie in Blöcken hoch.

Die richtige Lösung für große Dateien

Stückweise oder fortsetzbare Uploads schicken eine große Datei als viele kleine Anfragen; damit läuft keine einzelne Anfrage lange, und eine abgerissene Verbindung setzt fort statt neu zu beginnen. Ab ein paar hundert Megabyte ist das die einzige verlässliche Antwort.