nginx has no client_max_body_size - uploads/imports >1 MB get 413 through the proxy #83

Closed
opened 2026-07-15 19:49:55 +00:00 by claude-bot · 1 comment
Contributor

Severity: High · Confidence: High (config fact - verify against the live Caddy edge) · Effort: XS · Category: ops

Evidence

  • app/nginx.conf - entire file has no client_max_body_size directive (nginx default is 1 MB).
  • api/src/lib/upload.ts:68,78 (multer 2 GB), api/src/routes/import.ts:14 (500 MB), api/src/routes/media.ts:38-55 (500 MB video / 50 MB audio).
  • Architecture: Browser → nginx (app:80) → /api/* → api:3000.

Problem
The bundled nginx is the in-stack proxy for /api/* and sets no body-size limit, so nginx's 1 MB default applies. Any POST body over 1 MB - essentially every video, most images, every Twitter/Bluesky archive ZIP - is rejected with 413 before reaching multer.

Impact
Core media-upload and archive-import features are non-functional through the production proxy for anything but tiny files. Verify: if uploads work on the live instance, the Caddy edge is overriding this - in which case the bundled config is still wrong for clean-machine reproducibility.

Fix
Add client_max_body_size 2g; (or per-location limits matching the route caps) to the /api/ block in app/nginx.conf.

Acceptance criteria

  • A >1 MB image uploads successfully through the app nginx proxy.
  • A multi-MB Twitter/Bluesky archive imports through the proxy.

Filed from the 2026-07-15 codebase audit. Full report: docs/.internal/report-2026-07-15.md (gitignored).

**Severity:** High · **Confidence:** High (config fact - verify against the live Caddy edge) · **Effort:** XS · Category: ops **Evidence** - `app/nginx.conf` - entire file has no `client_max_body_size` directive (nginx default is 1 MB). - `api/src/lib/upload.ts:68,78` (multer 2 GB), `api/src/routes/import.ts:14` (500 MB), `api/src/routes/media.ts:38-55` (500 MB video / 50 MB audio). - Architecture: Browser → nginx (app:80) → `/api/*` → api:3000. **Problem** The bundled nginx is the in-stack proxy for `/api/*` and sets no body-size limit, so nginx's 1 MB default applies. Any POST body over 1 MB - essentially every video, most images, every Twitter/Bluesky archive ZIP - is rejected with 413 before reaching multer. **Impact** Core media-upload and archive-import features are non-functional through the production proxy for anything but tiny files. **Verify:** if uploads work on the live instance, the Caddy edge is overriding this - in which case the bundled config is still wrong for clean-machine reproducibility. **Fix** Add `client_max_body_size 2g;` (or per-location limits matching the route caps) to the `/api/` block in `app/nginx.conf`. **Acceptance criteria** - [ ] A >1 MB image uploads successfully through the app nginx proxy. - [ ] A multi-MB Twitter/Bluesky archive imports through the proxy. --- _Filed from the 2026-07-15 codebase audit. Full report: `docs/.internal/report-2026-07-15.md` (gitignored)._
Author
Contributor

Fixed in 9a87882 (v7.1.0 wave 1).

Added client_max_body_size 2g; to the /api/ proxy block in app/nginx.conf — matches the largest route cap (multer 2 GB); the per-route limits still enforce tighter caps per endpoint. Verified on the dev server: the directive is present in the running app container (grep client_max_body_size /etc/nginx/...client_max_body_size 2g;) and health is ok. CI #3640 green.

Note for the live edge: if uploads already worked in production, the Caddy edge was overriding nginx — this fixes the bundled config for clean-machine reproducibility regardless.

Fixed in `9a87882` (v7.1.0 wave 1). Added `client_max_body_size 2g;` to the `/api/` proxy block in `app/nginx.conf` — matches the largest route cap (multer 2 GB); the per-route limits still enforce tighter caps per endpoint. Verified on the dev server: the directive is present in the running app container (`grep client_max_body_size /etc/nginx/...` → `client_max_body_size 2g;`) and health is `ok`. CI #3640 green. Note for the live edge: if uploads already worked in production, the Caddy edge was overriding nginx — this fixes the bundled config for clean-machine reproducibility regardless.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/TeaLeaves#83
No description provided.