HTTP 413 Payload Too Large | Causes and Solutions

A 413 Payload Too Large error occurs when the request body exceeds the server's configured limit. Learn causes, troubleshooting steps, and how to handle large uploads in your applications.

A 413 Payload Too Large error occurs when the request body size exceeds the maximum allowed by the server. This prevents clients from sending oversized payloads that could overwhelm server resources or storage. It belongs to the 4xx client error class in the HTTP status codes specification—meaning the fix is always on the client side, not the server.

413 Payload Too Large

What 413 Payload Too Large Means

The HTTP Definition

Per RFC 9110, 413 indicates “the server is refusing to process a request because the request content is larger than what the server is willing or able to process.”

Key characteristics:

  • This is a client error (4xx class)
  • The server explicitly refuses the request
  • The server may close the connection or suggest retry with smaller payload
  • The Retry-After header may be included

Official Name Change

HTTP/1.1 used “413 Request Entity Too Large.” HTTP/2 and later use “413 Payload Too Large” (RFC 9110).

Common Causes of 413 Errors

1. Web Server Body Size Limits

Nginx:

# Default: 1MB
client_max_body_size 1m;

Apache:

# Default: 0 (unlimited in older versions)
LimitRequestBody 10485760

2. Application Framework Limits

Node.js (Express):

app.use(express.json({ limit: '1mb' }));
app.use(express.urlencoded({ limit: '1mb', extended: true }));

Django:

DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440 # 2.5 MB

PHP:

post_max_size = 8M
upload_max_filesize = 2M

3. CDN or Proxy Limits

CDNs and reverse proxies often have their own limits:

  • Cloudflare: 100MB for free plans
  • AWS CloudFront: Configurable
  • Azure CDN: 100MB default
  • Azion: Configurable per application via Rules Engine

4. Load Balancer Limits

Cloud load balancers enforce limits:

  • AWS ALB: 100KB for headers, larger for body
  • Google Cloud Load Balancing: 1MB default

5. WAF Rules

Web Application Firewalls may block large payloads:

  • ModSecurity rules
  • Cloud WAF policies
  • Custom security rules

Troubleshooting 413 Errors

Step 1: Identify Where the Limit Is

Client → CDN → Load Balancer → Web Server → Application
↑ ↑ ↑ ↑
limit? limit? limit? limit?

The error response headers help identify the source:

HTTP/1.1 413 Payload Too Large
Server: nginx # Generated by Nginx
Content-Type: text/html

Step 2: Check Web Server Configuration

Nginx:

Terminal window
grep -r "client_max_body_size" /etc/nginx/

Apache:

Terminal window
grep -r "LimitRequestBody" /etc/apache2/

Step 3: Check Application Limits

Node.js:

// Check middleware configuration
app.use(express.json({ limit: '10mb' }));

PHP:

Terminal window
php -i | grep -E "(post_max_size|upload_max_filesize)"

Step 4: Check CDN/WAF Logs

  • Cloudflare: Security Events
  • AWS WAF: CloudWatch metrics
  • ModSecurity: Audit logs
  • Azion: Real-Time Events → filter by status 413

Step 5: Test with Different Sizes

Terminal window
# Test with specific payload size
dd if=/dev/zero bs=1M count=5 | curl -X POST -H "Content-Type: application/json" --data-binary @- https://example.com/upload

How to Fix 413 Errors

Increase Nginx Limit

http {
# Global limit
client_max_body_size 100m;
}
server {
# Per-server limit
client_max_body_size 50m;
location /api/upload {
# Per-location limit
client_max_body_size 500m;
}
}

Increase Apache Limit

<Directory /var/www/html/uploads>
LimitRequestBody 52428800
</Directory>

Increase Application Limits

Express:

app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));

NestJS:

app.use(json({ limit: '50mb' }));

Django:

DATA_UPLOAD_MAX_MEMORY_SIZE = 52428800 # 50 MB
FILE_UPLOAD_MAX_MEMORY_SIZE = 52428800

PHP:

post_max_size = 50M
upload_max_filesize = 50M

Configure CDN Limits

Cloudflare:

  • Increase plan limits
  • Use direct origin uploads
  • Use Cloudflare R2 or Workers

AWS CloudFront:

  • Use signed URLs for large uploads
  • Upload directly to S3

Azion:

  • Configure request body size limit via Rules Engine
  • Use Edge Storage with presigned URLs for large uploads
  • Upload directly to Azion Edge Storage bypassing size limits at the proxy layer

Handling Large Uploads Properly

1. Chunked Uploads

Split large files into smaller chunks:

async function uploadFile(file) {
const chunkSize = 5 * 1024 * 1024; // 5MB chunks
const chunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i &lt; chunks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
await uploadChunk(chunk, i, chunks, file.name);
}
await completeUpload(file.name, chunks);
}

2. Direct-to-Storage Uploads

Upload directly to object storage:

// Get presigned URL from server
const { url, fields } = await fetch('/api/upload-url').then(r => r.json());
// Upload directly to S3
const formData = new FormData();
Object.entries(fields).forEach(([key, value]) => formData.append(key, value));
formData.append('file', file);
await fetch(url, { method: 'POST', body: formData });

3. Streaming Uploads

Stream large payloads without loading into memory:

app.post('/upload', (req, res) => {
const fileStream = fs.createWriteStream('/uploads/file.dat');
req.pipe(fileStream)
.on('error', (err) => res.status(500).send('Upload failed'))
.on('finish', () => res.send('Upload complete'));
});

4. Validate Before Upload

Check file size client-side before uploading:

const MAX_SIZE = 50 * 1024 * 1024; // 50MB
document.getElementById('file').addEventListener('change', (e) => {
const file = e.target.files[0];
if (file.size &gt; MAX_SIZE) {
alert(`File too large. Maximum size is ${MAX_SIZE / 1024 / 1024}MB`);
e.target.value = '';
}
});

Security Considerations

DoS Prevention

Large payloads can be used for denial of service:

  • Set reasonable limits based on use case
  • Limit total request time, not just size
  • Implement rate limiting per client

Memory Limits

Prevent memory exhaustion:

// Use streaming for large uploads
app.use(express.raw({
limit: '50mb',
type: 'application/octet-stream'
}));

Input Validation

Always validate uploaded content:

const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'application/pdf'];
app.post('/upload', (req, res) => {
if (!ALLOWED_TYPES.includes(req.file.mimetype)) {
return res.status(415).send('Unsupported media type');
}
// Scan for viruses, validate structure, etc.
});

Client-Side Error Handling

Handle 413 gracefully in your client:

async function uploadFile(file) {
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
if (response.status === 413) {
const max = response.headers.get('X-Max-Size');
throw new Error(`File too large. Maximum size is ${max} bytes`);
}
if (!response.ok) throw new Error('Upload failed');
return response.json();
} catch (error) {
console.error('Upload error:', error);
throw error;
}
}

Monitoring 413 Errors

Track these metrics:

  • 413 rate: Percentage of requests rejected for size
  • Average rejected size: Understand typical oversize payloads
  • Top endpoints: Which endpoints receive oversized requests
  • Client patterns: Identify clients consistently sending large payloads

Alert thresholds:

  • Sudden spike in 413s: Possible attack or misconfigured client
  • Consistent 413s from legitimate clients: Limits too restrictive

Frequently Asked Questions

What’s the default Nginx limit? 1MB (client_max_body_size 1m).

What’s the default Apache limit? Varies by version. Modern versions often have no limit by default.

How do I handle very large file uploads? Use chunked uploads, presigned URLs to cloud storage, or streaming uploads.

Can I return the max size in the error response? Yes, add a custom header: X-Max-Body-Size: 10485760.

Should I allow unlimited uploads? No. Always set limits to prevent DoS attacks and resource exhaustion.

How do I test upload limits? Use dd to create test files of specific sizes, then upload with curl.

stay up to date

Subscribe to our Newsletter

Get the latest product updates, event highlights, and tech industry insights delivered to your inbox.