Skip to content

[FIX] Document uploads >1 MB fail in staging/production — Nginx client_max_body_size not configured #202

@sage-ali

Description

@sage-ali

Bug Description

Document uploads larger than ~1 MB fail in staging and production with a 413 Request Entity Too Large error. The NestJS application code allows up to 5 MB per file — the block happens at the Nginx layer before the request reaches the app.

Steps to Reproduce

  1. Authenticate and call POST /api/v1/funnels/upload with a valid PDF, DOCX, or PPTX file between 1 MB and 5 MB
  2. Observe a 413 Request Entity Too Large response from Nginx
  3. Note that the NestJS application logs show no request received for that call

Expected Behavior

Files up to 5 MB (the configured MAX_UPLOAD_BYTES = 5_242_880) are accepted and processed. Uploading a 3 MB PDF should return 201 Created with upload tracking data.

Current Behavior

Any upload exceeding ~1 MB is rejected by Nginx before it reaches NestJS. The 413 comes from the reverse proxy, not the application.

Root Cause

Nginx client_max_body_size is not set — it defaults to 1m (1 megabyte) in all standard Nginx installations. No Nginx config exists in this repository; the deployment relies on the OS/image default, which caps request bodies at exactly 1 MB.

The NestJS/Multer layer is correctly configured:

  • src/modules/upload/constants/upload.constants.tsMAX_UPLOAD_BYTES = 5_242_880 (5 MiB)
  • src/modules/upload/upload.controller.ts — Multer limits.fileSize = MAX_UPLOAD_BYTES
  • src/modules/upload/upload.service.ts — service-level re-validation against MAX_UPLOAD_BYTES

None of these run because Nginx rejects the request first.

Secondary Issue — express.json() missing limit in main.ts

// src/main.ts
httpAdapter.use(
  express.json({
    verify: (req, _res, buf) => { req.rawBody = buf; },
    // ← no `limit` — defaults to Express's 100 KB cap
  }),
);

This does not affect multipart file uploads (Multer handles Content-Type: multipart/form-data independently), but any endpoint that receives a large JSON body would fail silently with a 413 or truncation error. Should be set explicitly: limit: '1mb' or appropriate value.

Possible Solution

Fix 1 — Nginx config (DevOps): Add to the API server block or location block:

client_max_body_size 10m;

Set to at least 6m (Multer's 5 MB limit + multipart envelope overhead). 10m gives headroom.

Fix 2 — main.ts (application): Make the JSON body limit explicit to match intent:

httpAdapter.use(
  express.json({
    limit: '1mb',
    verify: (req, _res, buf) => { req.rawBody = buf; },
  }),
);
httpAdapter.use(express.urlencoded({ extended: true, limit: '1mb' }));

Additional Context

  • Affected endpoint: POST /api/v1/funnels/upload
  • Allowed file types: PDF, DOC, DOCX, PPT, PPTX (up to 5 MB each, up to 3 files per request)
  • The 413 in staging/production is returned by Nginx — check response headers for Server: nginx to confirm
  • No Nginx config exists in this repo — fix must be applied to the deployment infrastructure config

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions