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