sindresorhus/got · error · Error

Failed to parse Link header: ${value}

Error message

Failed to parse Link header: ${value}

What it means

From `splitHeaderValue` in parse-link-header.ts:51. Got walks the Link header character-by-character tracking quote/escape state; if the input ends with an open quote or a dangling backslash escape, the parser considers the header malformed and throws. This guards the Link-pagination feature (`pagination.paginate` returning a `link` header) against feeding garbage into `URL`.

Source

Thrown at source/core/parse-link-header.ts:51

		if (!inQuotes && character === '>') {
			inReference = false;
			current += character;
			continue;
		}

		// Link headers use both quoted strings and <URI-reference> values, so raw
		// splitting on `,` / `;` would break valid values containing those characters.
		if (!inQuotes && !inReference && character === separator) {
			values.push(current);
			current = '';
			continue;
		}

		current += character;
	}

	if (inQuotes || isEscaped) {
		throw new Error(`Failed to parse Link header: ${value}`);
	}

	values.push(current);
	return values;
};

export default function parseLinkHeader(link: string) {
	const parsed = [];

	const items = splitHeaderValue(link, ',');

	for (const item of items) {
		// https://tools.ietf.org/html/rfc5988#section-5
		const [rawUriReference, ...rawLinkParameters] = splitHeaderValue(item, ';') as [string, ...string[]];
		const trimmedUriReference = rawUriReference.trim();

		// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
		if (trimmedUriReference[0] !== '<' || trimmedUriReference.at(-1) !== '>') {

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Inspect the raw `Link` header from the failing response (curl -i or `response.headers.link`) and report it to the upstream maintainer.
  2. If you control the server, ensure all quoted parameter values are closed and escapes are paired.
  3. Disable Got's automatic link parsing (`pagination` off) if the endpoint is known-broken and you don't need cursor walking.
  4. Pre-sanitize the header before passing to a manual Link parser if you must tolerate malformed upstreams.

Example fix

// before: upstream sends  Link: </p2>; rel="next
// (unterminated quote)

// after: fix the server to send  Link: </p2>; rel="next"
Defensive patterns

Strategy: try-catch

Validate before calling

function looksBalanced(header) {
  let quotes = 0, escaped = false;
  for (const ch of header) {
    if (escaped) { escaped = false; continue; }
    if (ch === '\\') { escaped = true; continue; }
    if (ch === '"') quotes++;
  }
  return !escaped && quotes % 2 === 0;
}
if (!looksBalanced(response.headers.link ?? '')) {
  // skip pagination
}

Try / catch

try {
  for await (const page of got.paginate(url)) { /* ... */ }
} catch (error) {
  if (error.message.startsWith('Failed to parse Link header')) {
    // upstream sent a malformed Link header; fall back to manual paging
  } else throw error;
}

Prevention

When it happens

Trigger: A server returns a `Link` header with an unterminated quoted value (e.g. `</page2>; rel="next`, missing closing quote) or a trailing backslash. Got attempts to parse it for pagination and throws at line 51.

Common situations: Misbehaving/legacy upstream proxies that truncate headers; a CDN rewriting headers and mangling quotes; an origin returning a hand-built Link header with a typo; enabling `pagination` against an endpoint whose `Link` is non-RFC8288 compliant.

Related errors


AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03). Data as JSON: /data/errors/bf55abd2964f559f.json. Report an issue: GitHub.