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
- Inspect the raw `Link` header from the failing response (curl -i or `response.headers.link`) and report it to the upstream maintainer.
- If you control the server, ensure all quoted parameter values are closed and escapes are paired.
- Disable Got's automatic link parsing (`pagination` off) if the endpoint is known-broken and you don't need cursor walking.
- 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
- Sanity-check the `Link` header before enabling pagination against an unknown endpoint.
- Report malformed headers upstream and pin pagination to known-good endpoints.
- Add a regression test using a captured raw header from the real upstream.
- Log `response.headers.link` when pagination fails to aid diagnosis.
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
- Invalid format of the Link header reference: ${trimmedUriRef
- Unexpected end of Link header parameters: ${rawLinkParameter
- Failed to parse Link header: ${link}
- `url` protocol must be followed by `//`
AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03).
Data as JSON: /data/errors/bf55abd2964f559f.json.
Report an issue: GitHub.