denoland/deno · error · NodeError
ERR_HTTP_BODY_NOT_ALLOWED
ERR_HTTP_BODY_NOT_ALLOWED
Error message
Adding content for this request method or response status is not allowed.
What it means
Some messages must not carry a body: _hasBody is set false for HEAD responses and for 204/304 status codes (see ServerResponse in _http_server.js). If the server was created with rejectNonStandardBodyWrites: true (kRejectNonStandardBodyWrites), write_() throws ERR_HTTP_BODY_NOT_ALLOWED instead of silently dropping the write.
Source
Thrown at ext/node/polyfills/_http_outgoing.ts:1416
);
}
msg[kBytesWritten] += len;
}
if (!msg._header) {
if (fromEnd) {
len ??= typeof chunk === "string"
? Buffer.byteLength(chunk, encoding)
: TypedArrayPrototypeGetByteLength(chunk);
msg._contentLength = len;
}
msg._implicitHeader();
}
if (!msg._hasBody) {
if (msg[kRejectNonStandardBodyWrites]) {
throw new ERR_HTTP_BODY_NOT_ALLOWED();
}
debug(
"This type of response MUST NOT have a body. " +
"Ignoring write() calls.",
);
(globalThis as any).process.nextTick(callback);
return true;
}
// Auto-corking
if (!fromEnd && msg.socket && !msg.socket.writableCorked) {
msg.socket.cork();
(globalThis as any).process.nextTick(connectionCorkNT, msg.socket);
}
let ret;
if (msg.chunkedEncoding && chunk.length !== 0) {
len ??= typeof chunk === "string"View on GitHub (pinned to 89f33cbef2)
Solutions
- Skip the body for bodyless messages: `if (req.method !== 'HEAD' && res.statusCode !== 204 && res.statusCode !== 304)`
- End bodyless responses with res.end() (no arguments) - that never throws
- If you rely on lenient behavior, do not pass rejectNonStandardBodyWrites: true when creating the server (it defaults to false)
Example fix
// before
const server = http.createServer({ rejectNonStandardBodyWrites: true }, (req, res) => {
res.writeHead(204);
res.end('{}'); // throws ERR_HTTP_BODY_NOT_ALLOWED
});
// after
const server = http.createServer({ rejectNonStandardBodyWrites: true }, (req, res) => {
res.writeHead(204);
res.end(); // 204 must not have a body
}); Defensive patterns
Strategy: validation
Validate before calling
function canHaveBody(req: http.IncomingMessage, res: http.ServerResponse): boolean {
return req.method !== 'HEAD' && res.statusCode !== 204 && res.statusCode !== 304;
}
if (canHaveBody(req, res)) res.write(body);
res.end(); Try / catch
try {
res.write(body);
} catch (e) {
if (e?.code === 'ERR_HTTP_BODY_NOT_ALLOWED') return; // bodyless message - drop
throw e;
} Prevention
- Default handlers to res.end() without a chunk for 204/304/HEAD paths
- Handle HEAD requests with the same headers but no body
- Remember rejectNonStandardBodyWrites is opt-in; enabling it converts silent drops into throws
When it happens
Trigger: http.createServer({ rejectNonStandardBodyWrites: true }, (req,res) => { res.statusCode = 204; res.end('nope'); }) or writing a body to a response for a HEAD request.
Common situations: Shared handler code that always writes a body but is also routed for HEAD requests and 204/304 'empty' responses (delete/update endpoints); strict-mode servers surfacing previously-silent bugs after enabling the option.
Related errors
- Invalid header name: "${name}"
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_URL
- ERR_UNESCAPED_CHARACTERS
- ERR_INVALID_HTTP_TOKEN
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/2635ddc69301f4ac.
Report an issue: GitHub.