denoland/deno · error · TypeError

Invalid header name

Error message

Invalid header name: "${name}"

What it means

appendHeader implements the Fetch spec's 'append a header' algorithm used by the Headers mutation methods (append/set). The name must consist solely of HTTP token code points (validated by HTTP_TOKEN_CODEPOINT_RE with a cache); anything else throws a TypeError showing the offending name.

Solutions

  1. Pass only the field name (letters, digits, and !#$%&'*+.^_`|~-) and the value separately
  2. Split 'Key: value' strings on the first ':' before appending
  3. Sanitize dynamic names against the token regex before calling append/set

Example fix

// before
headers.append("Content-Type: application/json", "");

// after
headers.append("Content-Type", "application/json");
Defensive patterns

Strategy: type-guard

Validate before calling

const HTTP_TOKEN_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
if (!HTTP_TOKEN_RE.test(name)) {
  // reject or sanitize before calling headers.append/set
}

Type guard

function isValidHeaderName(name: unknown): name is string {
  return typeof name === "string" && /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name);
}

Prevention

When it happens

Trigger: `h.append("Content-Type:", "text/html")` (colon in the name); `h.append("a b", "v")` (space); an empty name; non-ASCII names like "café"; `h.set(String(arr))` producing a comma-joined name.

Common situations: Appending a full header line "Key: value" instead of just the key; header names assembled from user/config input; concatenating arrays into a name.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/820313e829a498b7. Report an issue: GitHub.

Appendix: source

Thrown at ext/fetch/20_headers.js:173

  HEADER_CACHE_SIZE++;
  HEADER_NAME_CACHE[name] = valid;

  return valid;
}

/**
 * https://fetch.spec.whatwg.org/#concept-headers-append
 * @param {Headers} headers
 * @param {string} name
 * @param {string} value
 */
function appendHeader(headers, name, value) {
  // 1.
  value = normalizeHeaderValue(value);

  // 2.
  if (!checkHeaderNameForHttpTokenCodePoint(name)) {
    throw new TypeError(`Invalid header name: "${name}"`);
  }
  if (!checkForInvalidValueChars(value)) {
    throw new TypeError(`Invalid header value: "${value}"`);
  }

  // 3.
  if (headers[_guard] == "immutable") {
    throw new TypeError("Cannot change header: headers are immutable");
  }

  // 7.
  const list = headerListFromHeaders(headers);
  const lowerNames = ensureLowerNames(headers);
  const lowercaseName = byteLowerCase(name);
  for (let i = 0; i < lowerNames.length; i++) {
    if (lowerNames[i] === lowercaseName) {
      name = list[i][0];
      break;

View on GitHub (pinned to 9ad36f7a2c)