{"record":{"id":"448ea0a077fdda6a","repo":"denoland/deno","slug":"err-http2-invalid-header-value","errorCode":"ERR_HTTP2_INVALID_HEADER_VALUE","errorMessage":"Invalid value \"${value}\" for header \"${name}\"","messagePattern":"Invalid value \"(.+?)\" for header \"(.+?)\"","errorType":"validation","errorClass":"NodeTypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/http2/compat.js","lineNumber":105,"sourceCode":"let statusConnectionHeaderWarned = false;\n\n// Defines and implements an API compatibility layer on top of the core\n// HTTP/2 implementation, intended to provide an interface that is as\n// close as possible to the current require('http') API\n\nconst assertValidHeader = hideStackFrames((name, value) => {\n  if (\n    name === \"\" ||\n    typeof name !== \"string\" ||\n    StringPrototypeIncludes(name, \" \")\n  ) {\n    throw new ERR_INVALID_HTTP_TOKEN.HideStackFramesError(\"Header name\", name);\n  }\n  if (isPseudoHeader(name)) {\n    throw new ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED.HideStackFramesError();\n  }\n  if (value === undefined || value === null) {\n    throw new ERR_HTTP2_INVALID_HEADER_VALUE.HideStackFramesError(value, name);\n  }\n  if (!isConnectionHeaderAllowed(name, value)) {\n    connectionHeaderMessageWarn();\n  }\n});\n\nfunction isPseudoHeader(name) {\n  switch (name) {\n    case HTTP2_HEADER_STATUS: // :status\n    case HTTP2_HEADER_METHOD: // :method\n    case HTTP2_HEADER_PATH: // :path\n    case HTTP2_HEADER_AUTHORITY: // :authority\n    case HTTP2_HEADER_SCHEME: // :scheme\n      return true;\n    default:\n      return false;\n  }\n}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/http2/compat.js#L87-L123","documentation":"assertValidHeader in http2 compat also checks the value: a header value of undefined or null throws ERR_HTTP2_INVALID_HEADER_VALUE, because HTTP/2 cannot encode a header with no value. Every header set through setHeader/appendHeader/setTrailer/writeHead must carry an actual value (string, number, or array).","triggerScenarios":"res.setHeader(\"x-optional\", undefined) from optional config or destructuring; object-spread headers containing undefined fields passed to writeHead(); trailer values fetched from a Map/lookup that returned null or undefined.","commonSituations":"Optional feature flags: setHeader(\"x-deprecated\", flags.deprecated) where the field is absent; spreads like { ...commonHeaders, ...overrides } where some keys are undefined; JSON config with null values fed straight into headers.","solutions":["Skip the header entirely when the value is null or undefined","Default it when an empty value is meaningful: setHeader(name, value ?? \"\")","Filter header maps before writeHead: Object.fromEntries(Object.entries(h).filter(([, v]) => v != null))"],"exampleFix":"// before\nfor (const [k, v] of Object.entries(config.headers)) res.setHeader(k, v); // undefined v throws\n\n// after\nfor (const [k, v] of Object.entries(config.headers)) {\n  if (v !== undefined && v !== null) res.setHeader(k, v);\n}","handlingStrategy":"validation","validationCode":"function hasHeaderValue(v) {\n  return v !== undefined && v !== null;\n}\nfor (const [k, v] of Object.entries(headers)) {\n  if (hasHeaderValue(v)) res.setHeader(k, v);\n}","typeGuard":"function isDefiniteHeaderValue(\n  v: unknown,\n): v is string | number | string[] | number[] {\n  return v !== undefined && v !== null;\n}","tryCatchPattern":"try {\n  res.setHeader(k, v);\n} catch (err) {\n  if (err.code === \"ERR_HTTP2_INVALID_HEADER_VALUE\" && v == null) return; // just skip\n  throw err;\n}","preventionTips":["Filter null/undefined out of header maps before passing them to h2 APIs","Use nullish-coalescing defaults for optional headers instead of passing absent values"],"tags":["http2","headers","validation"],"backgroundTag":"invalid-http-header","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}