scalpel@labs: ~/glossary/canonical-link-header.mdx5 sections

Canonical Link Header

The canonical Link header (Link: <https://...>; rel="canonical") declares the authoritative URL for a response at the HTTP layer, exactly as the HTML link rel="canonical" tag does in the head. It is the only way to canonicalise non-HTML resources such as PDFs.

extension: Scalpel Redirectsupdated: 2026-08-14read_time: 2 min
less canonical-link-header.mdx

Why it matters

Two channels for the same signal means two places to disagree. A CDN-injected Link header contradicting the template's canonical tag splits your own vote. Google treats canonicals as hints weighed against other signals, so it resolves the conflict its way, not yours. The header is invisible in view-source; header-level auditing is the only way to know it exists.

How it works

The Link header is parsed according to RFC 8288. The browser or crawler reads the response header and extracts the canonical URL from the rel="canonical" parameter. Like the HTML tag, it is a suggestion for indexing, not a redirect.

For non-HTML resources like PDFs, the HTTP header is your only option. A PDF at /downloads/report.pdf can declare its canonical as a landing page using the header; no meta tag is possible in a binary file.

When both a Link header and an HTML canonical tag are present, search engines apply the same logic to both: the most restrictive or the most consistent signal usually wins.

What does not matter

A canonical Link header on a redirect chain's intermediate hops does not affect indexing, because indexing happens at the final page. A noindex on a 301 target is more relevant than a canonical on a hop that sends you there.

The header works on both HTTP and HTTPS, but Google will not act on an insecure redirect to HTTPS if you declare a canonical on the HTTP version. Keep the header consistent with your server architecture.

Code example

Correct header for a PDF canonicalising to its landing page:

HTTP/1.1 200 OK
Content-Type: application/pdf
Link: <https://example.com/reports/q4-summary>; rel="canonical"

[PDF binary content]

The same header on an HTML page with a conflicting meta tag:

<!-- Page at https://example.com/product?id=123&ref=email -->
<link rel="canonical" href="https://example.com/product?id=123" />
HTTP/1.1 200 OK
Link: <https://example.com/product>; rel="canonical"

In this case, the header says example.com/product (no query), and the meta tag says example.com/product?id=123 (with query). Google will consolidate the signals, favouring the simpler URL because it appears canonical in the config across both channels.

A correct nginx snippet declaring a canonical via header:

location /downloads/report.pdf {
  add_header Link "<https://example.com/reports>; rel=\"canonical\"" always;
}

How Scalpel shows it

Scalpel Redirects reads the Link header from every hop in a chain and surfaces any canonical found. The parsed, absolutised target is shown in a canonical hint chip on that hop, so you can verify the header is present and correct across all machines in your stack.

Sources