How to Fix Nginx 411 Content-Length Required Error for PUT Requests


2 views

When making HTTP PUT requests to an Nginx server without including the Content-Length header, you'll receive a 411 "Length Required" error. This is because Nginx strictly follows RFC 7230 standards which mandate this header for requests with bodies.

You'll commonly encounter this when:

PUT /api/upload HTTP/1.1
Host: example.com
Content-Type: application/json

{"key":"value"}

Nginx rejects this with:

HTTP/1.1 411 Length Required
Server: nginx
Content-Type: text/html
Content-Length: 176

Option 1: Add Content-Length in Client Code

// Node.js example
const http = require('http');
const data = JSON.stringify({ key: 'value' });

const options = {
  hostname: 'example.com',
  port: 80,
  path: '/api/upload',
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(data)
  }
};

const req = http.request(options, (res) => {
  // handle response
});

req.write(data);
req.end();

Option 2: Nginx Configuration Tweaks

While Nginx doesn't officially support disabling this check, you can use chunked transfer encoding:

location /api/ {
  chunked_transfer_encoding on;
  # Other proxy settings...
}

Option 3: Use Transfer-Encoding Instead

PUT /api/upload HTTP/1.1
Host: example.com
Content-Type: application/json
Transfer-Encoding: chunked

7
{"key":"value"}
0

Modern RESTful APIs often expect PUT requests for resource updates. Many client libraries (especially browser-based ones) might omit Content-Length for streaming scenarios. Understanding these HTTP nuances prevents frustrating debugging sessions.

Use cURL to verify your fixes:

# Without fix (will fail)
curl -X PUT -H "Content-Type: application/json" -d '{"test":true}' http://localhost/api

# With Content-Length
curl -X PUT -H "Content-Type: application/json" -H "Content-Length: 13" -d '{"test":true}' http://localhost/api

# With chunked encoding
curl -X PUT -H "Content-Type: application/json" -H "Transfer-Encoding: chunked" -d '{"test":true}' http://localhost/api

While workarounds exist, properly setting Content-Length is preferred for:

  • Better connection reuse
  • More accurate progress tracking
  • Efficient memory allocation on server

When working with HTTP PUT requests in Nginx, you might encounter the frustrating 411 Length Required response. This happens because Nginx strictly requires a Content-Length header for certain request methods by default.

Nginx implements this behavior for security and protocol compliance reasons:

  • Prevents certain types of denial-of-service attacks
  • Ensures proper handling of request bodies
  • Maintains HTTP/1.1 protocol compliance

Here are several approaches to handle this issue:

1. Always Include Content-Length (Recommended)

The most proper solution is to include the header in your requests:

PUT /api/resource HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 27

{"data": "example payload"}

2. Modify Nginx Configuration

For cases where you can't control client headers, add this to your nginx.conf:

server {
    ...
    client_header_buffer_size 8k;
    large_client_header_buffers 4 32k;
    chunked_transfer_encoding on;
}

3. Use Transfer-Encoding: chunked

When streaming data, consider chunked transfer encoding:

PUT /upload HTTP/1.1
Host: api.example.com
Transfer-Encoding: chunked

5
Hello
6
 World
0

For specific use cases, you might need deeper Nginx customization:

location /upload {
    client_max_body_size 100M;
    client_body_buffer_size 128k;
    client_body_in_file_only clean;
    client_body_temp_path /var/nginx/client_body_temp;
}

Verify your changes with curl:

curl -X PUT -H "Transfer-Encoding: chunked" -d @payload.txt http://localhost