denoland/deno · error · NodeTypeError

ERR_HTTP_INVALID_HEADER_VALUE

ERR_HTTP_INVALID_HEADER_VALUE

Error message

Invalid value "${value}" for header "${name}"

What it means

validateHeaderValue() throws ERR_HTTP_INVALID_HEADER_VALUE when the value passed to setHeader()/appendHeader() is exactly `undefined`. The library refuses to serialize a header whose value was never provided.

Source

Thrown at ext/node/polyfills/_http_outgoing.ts:1299

      }
    },
    "OutgoingMessage.prototype._headerNames is deprecated",
    "DEP0066",
  ),
});

export const validateHeaderName = hideStackFrames(
  (name: string, label?: string): void => {
    if (typeof name !== "string" || !name || !checkIsHttpToken(name)) {
      throw new ERR_INVALID_HTTP_TOKEN(label || "Header name", name);
    }
  },
);

export const validateHeaderValue = hideStackFrames(
  (name: string, value: string): void => {
    if (value === undefined) {
      throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
    }
    if (checkInvalidHeaderChar(value)) {
      debug('Header "%s" contains invalid characters', name);
      throw new ERR_INVALID_CHAR("header content", name);
    }
  },
);

export function parseUniqueHeadersOption(headers) {
  if (!ArrayIsArray(headers)) {
    return null;
  }

  const unique = new SafeSet();
  const l = headers.length;
  for (let i = 0; i < l; i++) {
    unique.add(StringPrototypeToLowerCase(headers[i]));
  }

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Skip the header when the value is undefined: `if (v !== undefined) res.setHeader(name, v)`
  2. Provide a sensible default: `res.setHeader('X-Owner', v ?? 'unknown')`
  3. Coerce explicitly with String(v) when the value may be a number/boolean

Example fix

// before
res.setHeader('X-Owner', options.owner); // options.owner === undefined -> throws

// after
if (options.owner !== undefined) res.setHeader('X-Owner', options.owner);
Defensive patterns

Strategy: validation

Validate before calling

// skip headers whose value was never provided
for (const [k, v] of Object.entries(headers)) {
  if (v === undefined) continue;
  res.setHeader(k, v);
}

Type guard

function hasDefinedHeaderValue(v: unknown): v is string | number | string[] {
  return v !== undefined;
}

Try / catch

try {
  res.setHeader(name, value);
} catch (e) {
  if (e?.code === 'ERR_HTTP_INVALID_HEADER_VALUE' && value === undefined) return;
  throw e;
}

Prevention

When it happens

Trigger: res.setHeader('X-Trace-Id', undefined) - typically a config lookup or destructuring that returned undefined, or an optional field forwarded straight into a header.

Common situations: Optional metadata: `res.setHeader('X-Owner', options.owner)` where owner is sometimes absent; spreading partial objects into header calls; env-driven config where a var is unset.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/f61ad013a4fd1c92. Report an issue: GitHub.