fix: Video-Upload als roher Body statt multipart — beseitigt die 502-Ursache
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m10s

Live beobachtet: der Upload scheitert mit HTTP 502, nicht mit 504. Das ist
ein wesentlicher Unterschied. 502 bedeutet, dass der vorgeschaltete Proxy
vom Backend gar keine Antwort bekam — der Prozess hat die Verbindung mitten
im Request fallen gelassen. Eine Zeitueberschreitung waere 504. Die bisher
verfolgte Timeout-Spur war damit falsch.

Uebrig blieb als Erklaerung der Arbeitsspeicher, und dort lag noch die
eigentliche Ursache: request.formData() liest den GESAMTEN Body in den
Speicher, bevor eine einzige Zeile eigener Code laeuft. Der vorherige
Streaming-Umbau hat nur die zusaetzlichen Kopien danach beseitigt
(arrayBuffer, Buffer, readFile) — diese erste nicht. Bei einem Video bis
100 MB genuegt das, um zusammen mit dem Grundverbrauch des Servers das
Speicherlimit des Pods zu sprengen; der Kernel beendet den Prozess
(OOMKilled), und der Proxy meldet 502.

Die Datei kommt jetzt als roher Request-Body statt als multipart/form-data.
Damit laesst sich request.body direkt auf die Platte durchreichen, und der
Speicherbedarf haengt nicht mehr von der Dateigroesse ab. Ein Formularfeld
wurde ohnehin nicht gebraucht, es wird genau eine Datei uebertragen. Die
Groessengrenze prueft jetzt ein mitzaehlender Transform-Stream, weil
Content-Length nur eine Ankuendigung des Clients ist.

Gemessen im Produktions-Build mit einem 95-MB-Video: Status 200 nach 5,9
Sekunden, Arbeitsspeicher des Servers von 67 MB auf in der Spitze 149 MB —
also rund ein Drittel des Limits von 512Mi, mit dem der Pod bisher lief.

Ausserdem berichtigt: der eigene Meldungstext behauptete bei 502 "fast
immer eine Zeitueberschreitung". Das ist falsch und hat die Fehlersuche in
die falsche Richtung gelenkt. 502 und 504 werden jetzt getrennt erklaert —
502 als weggebrochenes Backend (meist Speichermangel), 504 als echtes
Zeitlimit.
This commit is contained in:
Nick Szaunig committed 2026-09-15 02:27:11 +02:00
1 parent e8f0bd4f55
commit 96bb3d9c50
4 files changed
+120 -51

No files matched your search

+8 -4
View File
@@ -1142,8 +1142,10 @@ export const en: Dictionary = {
uploadErrorStatus: (status) =>
status === 413
? `The file was rejected because it is too large (HTTP 413). It never reached the shop — that limit comes from the reverse proxy or CDN in front of it.`
: status === 502 || status === 503 || status === 504 || status === 522 || status === 524
? `The server aborted processing (HTTP ${status}). This is almost always a timeout: processing takes longer than the proxy in front of it waits for a response.`
: status === 502
? `The server aborted processing (HTTP 502). The backend dropped the connection without answering — often because it ran out of memory. Please report this number to your technical contact.`
: status === 503 || status === 504 || status === 522 || status === 524
? `The server aborted processing (HTTP ${status}). This is a timeout: processing took longer than the proxy in front of it allows.`
: `The server responded unexpectedly (HTTP ${status}) — no usable reply. Please report this number to your technical contact.`,
uploadErrorNetwork: "The connection to the server was interrupted during the upload.",
},
@@ -1156,8 +1158,10 @@ export const en: Dictionary = {
uploadErrorStatus: (status) =>
status === 413
? `The video was rejected because it is too large (HTTP 413). It never reached the shop — that limit comes from the reverse proxy or CDN in front of it, not from the shop itself.`
: status === 502 || status === 503 || status === 504 || status === 522 || status === 524
? `The server aborted processing (HTTP ${status}). For videos this is almost always a timeout: re-encoding for the web takes longer than the proxy in front of it waits for a response. A shorter or smaller video usually gets through.`
: status === 502
? `The server aborted processing (HTTP 502). The backend dropped the connection without answering — for videos usually because it ran out of memory while processing. Please report this number to your technical contact.`
: status === 503 || status === 504 || status === 522 || status === 524
? `The server aborted processing (HTTP ${status}). This is a timeout: the upload took longer than the proxy in front of it allows. A shorter or smaller video usually gets through.`
: `The server responded unexpectedly (HTTP ${status}) — no usable reply. Please report this number to your technical contact.`,
uploadErrorNetwork: "The connection to the server was interrupted during the upload.",
},