This error occurs when the Content-Length header value does not match the actual size of the response body received. It typically happens when the server sends an incorrect header, a proxy modifies the response without updating headers, or compression is applied inconsistently.
The ERR_HTTP_CONTENT_LENGTH_MISMATCH error is thrown by Node.js when the HTTP client receives a response where the Content-Length header doesn't match the actual number of bytes in the response body. This is a data integrity check that Node.js performs to ensure complete and accurate data transmission. The Content-Length header tells the client how many bytes to expect in the response body. When Node.js receives fewer or more bytes than specified, it raises this error to prevent the application from processing incomplete or corrupted data. This error commonly occurs in scenarios involving proxies, load balancers, compression middleware, or when server-side code incorrectly calculates the body size before setting the header.
Ensure your server calculates the Content-Length header correctly using Buffer.byteLength() instead of string length:
const express = require('express');
const app = express();
app.get('/api/data', (req, res) => {
const data = JSON.stringify({ message: 'Hello, world!' });
// Correct: Use Buffer.byteLength for accurate byte count
res.setHeader('Content-Length', Buffer.byteLength(data, 'utf8'));
res.setHeader('Content-Type', 'application/json');
res.send(data);
});This is especially important for responses containing non-ASCII characters, where string length and byte length differ.
If you're using compression middleware, let Node.js calculate Content-Length automatically or use chunked encoding:
const compression = require('compression');
const express = require('express');
const app = express();
// Let compression middleware handle headers
app.use(compression());
app.get('/api/data', (req, res) => {
// Don't set Content-Length manually when using compression
res.json({ message: 'This will be compressed automatically' });
});Alternatively, explicitly remove Content-Length when applying compression:
app.use((req, res, next) => {
res.removeHeader('Content-Length');
next();
});For responses where size cannot be determined upfront, use chunked encoding instead of Content-Length:
app.get('/api/stream', (req, res) => {
res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('Content-Type', 'application/json');
// Don't set Content-Length - chunked encoding handles it
res.write('{"items":[');
// Stream data in chunks
for (let i = 0; i < 100; i++) {
res.write(JSON.stringify({ id: i }));
if (i < 99) res.write(',');
}
res.write(']}');
res.end();
});This is ideal for streaming responses, large files, or dynamically generated content.
If using a proxy or middleware that modifies responses, ensure it updates or removes Content-Length:
const { createProxyMiddleware } = require('http-proxy-middleware');
app.use('/api', createProxyMiddleware({
target: 'http://backend-server:3000',
changeOrigin: true,
onProxyRes: (proxyRes, req, res) => {
// Remove Content-Length if response is modified
if (proxyRes.headers['content-encoding']) {
delete proxyRes.headers['content-length'];
delete proxyRes.headers['content-encoding'];
}
}
}));This prevents mismatches when proxies decompress or modify responses.
To catch these errors early in development, enable strict content length validation:
const http = require('http');
const options = {
hostname: 'api.example.com',
port: 80,
path: '/data',
method: 'GET',
// Enable strict content length checking
strictContentLength: true
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Response:', data);
});
});
req.on('error', (err) => {
if (err.code === 'ERR_HTTP_CONTENT_LENGTH_MISMATCH') {
console.error('Content-Length mismatch detected:', err.message);
}
});
req.end();This will throw errors immediately when mismatches are detected rather than silently failing.
Character Encoding Considerations: When dealing with UTF-8 encoded strings, always use Buffer.byteLength(str, 'utf8') instead of str.length. For example, the string "café" has a length of 4 but a byte length of 5 because 'é' is encoded as two bytes in UTF-8.
HTTP/2 and Content-Length: In HTTP/2, Content-Length headers are optional and often omitted in favor of the protocol's built-in framing mechanism. If you're experiencing this error only with HTTP/1.1 connections, consider upgrading to HTTP/2.
Load Balancer Configuration: Some load balancers (nginx, HAProxy) may modify response bodies for health checks or content filtering. Check your load balancer logs and configuration to ensure Content-Length headers are properly handled when responses are modified.
Debugging Tips: Use tools like curl -v or Wireshark to inspect the actual HTTP headers and body size at the wire level. Compare the Content-Length header value with the actual bytes received to identify where the mismatch originates.
Performance Impact: Removing Content-Length and using chunked encoding may prevent HTTP keep-alive optimization in some cases, as the client cannot determine response boundaries without reading the entire chunked response. However, this is generally preferable to incorrect Content-Length values causing errors.
Error: Listener already called (once event already fired)
EventEmitter listener already called with once()
Error: EACCES: permission denied, open '/root/file.txt'
EACCES: permission denied
Error: Invalid encoding specified (stream encoding not supported)
How to fix Invalid encoding error in Node.js readable streams
Error: EINVAL: invalid argument, open
EINVAL: invalid argument, open
TypeError: readableLength must be a positive integer (stream config)
TypeError: readableLength must be a positive integer in Node.js streams