$ headless-seo-check http://127.0.0.1:4311 --urls /hreflang-good,/hreflang-drift,/hreflang-dead,/hreflang-drift-dead,/hreflang-html-only --no-color --- stdout+stderr --- headless-seo-check: checking http://127.0.0.1:4311 … headless-seo-check: 5 of 5 URLs selected, from --urls headless-seo-check http://127.0.0.1:4311 5 of 5 URLs checked, from --urls + /hreflang-good static, 324 words x /hreflang-drift static, 324 words error the Link: header and the HTML advertise different URLs for 1 language fr header: http://127.0.0.1:4311/fr/hreflang-drift fr HTML: http://127.0.0.1:4311/fr/slug-traduit fr the header target answers HTTP 200 + /hreflang-dead static, 327 words x /hreflang-drift-dead static, 327 words error the Link: header and the HTML advertise different URLs for 1 language fr header: http://127.0.0.1:4311/fr/nexiste-pas fr HTML: http://127.0.0.1:4311/fr/slug-traduit fr the header target does not exist (HTTP 404) error 1 hreflang target in the Link: header do not exist fr http://127.0.0.1:4311/fr/nexiste-pas — does not exist (HTTP 404) + /hreflang-html-only static, 325 words FAILED 3 blocking issues 2 × hreflang-drift 1 × hreflang-dead-target What to do hreflang-drift The Link: header and the HTML advertise different alternates for the same language, so the page has two sources of truth and one of them is wrong. Frameworks derive header alternates by swapping a locale prefix, which breaks the moment slugs are translated. Emit alternates in one place, not both. hreflang-dead-target An alternate points at a URL that does not exist. Google drops the whole hreflang cluster when one side is dead, so this costs you every language, not just the broken one. Fix the target or remove the alternate — an alternate that merely redirects is untidy, this one is not. --- exit code: 1 ---