Una subida que falla en una frontera de tamaño es un límite; consulta 413 Petición demasiado grande. Una subida que falla a medias, sin un tamaño constante, con la conexión cayéndose sin más, es un tiempo de espera en algún punto del camino.
Los tiempos de espera que hay que subir, todos
# 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 limita cuánto tiempo dedicará PHP a recibir la petición. Es distinto de max_execution_time, viene bajo por defecto y es lo que mata una subida lenta desde un teléfono.
Disco y espacio temporal
df -h /tmp /var/lib/php/tmp
grep upload_tmp_dir /etc/php/8.3/fpm/php.ini
Una subida se escribe primero en un archivo temporal. Si ese sistema de archivos se llena, la escritura falla a mitad de la transferencia y la conexión se cae sin dejar mensaje en ninguna parte.
Busca lo que quedó registrado
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 es el límite de tamaño. timed out y upstream prematurely closed son los tiempos de espera de arriba. Nada en absoluto suele significar que el navegador o un proxy se rindieron antes que el servidor.
La solución de verdad para archivos grandes
La subida por trozos o reanudable manda un archivo grande como muchas peticiones pequeñas, así ninguna petición dura mucho y una conexión caída se reanuda en vez de empezar de cero. Por encima de unos cientos de megabytes es la única respuesta fiable.