{"record":{"id":"2635ddc69301f4ac","repo":"denoland/deno","slug":"err-http-body-not-allowed","errorCode":"ERR_HTTP_BODY_NOT_ALLOWED","errorMessage":"Adding content for this request method or response status is not allowed.","messagePattern":"Adding content for this request method or response status is not allowed\\.","errorType":"exception","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_http_outgoing.ts","lineNumber":1416,"sourceCode":"      );\n    }\n\n    msg[kBytesWritten] += len;\n  }\n\n  if (!msg._header) {\n    if (fromEnd) {\n      len ??= typeof chunk === \"string\"\n        ? Buffer.byteLength(chunk, encoding)\n        : TypedArrayPrototypeGetByteLength(chunk);\n      msg._contentLength = len;\n    }\n    msg._implicitHeader();\n  }\n\n  if (!msg._hasBody) {\n    if (msg[kRejectNonStandardBodyWrites]) {\n      throw new ERR_HTTP_BODY_NOT_ALLOWED();\n    }\n    debug(\n      \"This type of response MUST NOT have a body. \" +\n        \"Ignoring write() calls.\",\n    );\n    (globalThis as any).process.nextTick(callback);\n    return true;\n  }\n\n  // Auto-corking\n  if (!fromEnd && msg.socket && !msg.socket.writableCorked) {\n    msg.socket.cork();\n    (globalThis as any).process.nextTick(connectionCorkNT, msg.socket);\n  }\n\n  let ret;\n  if (msg.chunkedEncoding && chunk.length !== 0) {\n    len ??= typeof chunk === \"string\"","sourceCodeStart":1398,"sourceCodeEnd":1434,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/_http_outgoing.ts#L1398-L1434","documentation":"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.","triggerScenarios":"http.createServer({ rejectNonStandardBodyWrites: true }, (req,res) => { res.statusCode = 204; res.end('nope'); }) or writing a body to a response for a HEAD request.","commonSituations":"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.","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)"],"exampleFix":"// before\nconst server = http.createServer({ rejectNonStandardBodyWrites: true }, (req, res) => {\n  res.writeHead(204);\n  res.end('{}'); // throws ERR_HTTP_BODY_NOT_ALLOWED\n});\n\n// after\nconst server = http.createServer({ rejectNonStandardBodyWrites: true }, (req, res) => {\n  res.writeHead(204);\n  res.end(); // 204 must not have a body\n});","handlingStrategy":"validation","validationCode":"function canHaveBody(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n  return req.method !== 'HEAD' && res.statusCode !== 204 && res.statusCode !== 304;\n}\nif (canHaveBody(req, res)) res.write(body);\nres.end();","typeGuard":null,"tryCatchPattern":"try {\n  res.write(body);\n} catch (e) {\n  if (e?.code === 'ERR_HTTP_BODY_NOT_ALLOWED') return; // bodyless message - drop\n  throw e;\n}","preventionTips":["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"],"tags":["http","status-codes","head","validation"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}