Rule catalogue
Every rule goflag can report: 25 judged per page, 28 across the whole site, 5 it states but will not answer, plus the hreflang reciprocity codes.
Page rules
Judged on one page at a time, from its <head>. Each rule is a pure function of the page, which is why a finding can always be reproduced from the URL alone.
| Rule | Severity | Rigor | What it checks |
|---|---|---|---|
| canonical.absolute | error | vendor-spec | `rel="canonical"` must be an absolute, fully-qualified URL |
| canonical.missing | warning | vendor-spec | Declare a `<link rel="canonical">` so search engines pick the right URL |
| description.length | warning | heuristic | Keep descriptions between 50 and 160 characters |
| description.missing | warning | spec-recommended | Provide a `<meta name="description">` on every indexable page |
| icons.apple-touch.missing | info | vendor-spec | Declare an `apple-touch-icon` for the iOS home screen |
| icons.manifest-mismatch | info | guideline | The manifest and the `<head>` must not disagree about the same icon |
| icons.missing | warning | guideline | Declare an icon — the tab, the bookmark and the share sheet all read one |
| icons.sizes-mismatch | info | guideline | A `sizes` attribute must describe the file it points at |
| icons.unreachable | warning | vendor-spec | A declared icon has to answer with an image |
| og.description.missing | info | vendor-spec | Set an explicit `og:description` for richer link unfurls |
| og.image.absolute | warning | vendor-spec | `og:image` must be an absolute URL |
| og.image.alt | warning | guideline | Describe the shared image with `og:image:alt` |
| og.image.alt.caption | info | guideline | `og:image:alt` describes the image, it does not repeat the title |
| og.image.dimensions | warning | vendor-spec | Declare `og:image:width` and `og:image:height` |
| og.image.missing | warning | vendor-spec | Provide at least one `og:image` so links unfurl with a preview |
| og.image.ratio | info | vendor-spec | Keep the shared image near the 1.91:1 the card is laid out for |
| og.image.reachable | error | vendor-spec | The URL in `og:image` has to answer with an image |
| og.image.sizes-mismatch | warning | guideline | `og:image:width` and `og:image:height` must be the image's real size |
| og.locale.alternates | warning | vendor-spec | `og:locale:alternate` and the hreflang cluster must name the same locales |
| og.locale.missing | warning | vendor-spec | A translated page has to say which locale it is in |
| og.title.missing | warning | vendor-spec | Set an explicit `og:title` instead of relying on `<title>` fallback |
| robots.conflict | error | vendor-spec | `robots`, `googlebot`, and `X-Robots-Tag` must not contradict each other |
| title.length | warning | heuristic | Keep `<title>` between 10 and 60 characters |
| title.missing | error | spec-required | Every page needs a non-empty `<title>` |
| viewport.missing | warning | guideline | Declare a `<meta name="viewport">` so mobile browsers render at the right scale |
Site rules
Judged across the whole crawl, because no single page carries the evidence. Fixing one of these usually fixes a whole column of findings at once.
| Rule | Severity | Rigor | What it checks |
|---|---|---|---|
| hreflang.cluster-incomplete | warning | vendor-spec | Every locale the sitemap publishes must appear in the route's `hreflang` cluster |
| hreflang.missing | error | vendor-spec | Pages on a multilingual site must advertise their locale alternates |
| icons.ico.missing | info | guideline | Serve a `/favicon.ico` at the root for the clients that ask blind |
| robots.blocks-page | error | vendor-spec | A page asking to be indexed must not be disallowed by robots.txt |
| robots.blocks-site | error | vendor-spec | `robots.txt` must not forbid crawling a site that asks to be indexed |
| robotstxt.cross-origin | warning | vendor-spec | `/robots.txt` should not redirect to another origin |
| robotstxt.invalid-line | warning | spec-required | Every line of robots.txt should parse as something |
| robotstxt.oversized | error | spec-required | Rules past 500 KiB of robots.txt are not guaranteed to be read |
| robotstxt.sitemap.relative | error | spec-required | A `Sitemap:` declaration must be an absolute URL |
| robotstxt.unknown-directive | info | guideline | Non-standard robots.txt directives are read by some crawlers and ignored by others |
| robotstxt.unreachable | error | spec-required | A robots.txt that errors is read as forbidding the whole site |
| sitemap.empty | warning | guideline | A sitemap that parses should list something |
| sitemap.entry.blocked-by-robots | error | vendor-spec | A sitemap must not list URLs that robots.txt forbids fetching |
| sitemap.entry.cross-host | error | spec-required | A sitemap should only list URLs on its own host |
| sitemap.entry.invalid-url | error | spec-required | Every `<loc>` must be an absolute, parseable URL |
| sitemap.entry.noindex | warning | vendor-spec | A sitemap must not list URLs that ask not to be indexed |
| sitemap.entry.non-canonical | warning | vendor-spec | A sitemap should list canonical URLs |
| sitemap.entry.out-of-scope | error | spec-required | A sitemap may only list URLs under its own directory |
| sitemap.entry.protocol-mismatch | warning | spec-required | A sitemap should not mix `http` and `https` entries |
| sitemap.entry.redirects | warning | guideline | A sitemap should list final URLs, not URLs that redirect |
| sitemap.entry.unreachable | error | vendor-spec | Every URL a sitemap lists must answer |
| sitemap.field.invalid | warning | spec-required | `<changefreq>` and `<priority>` must hold the values the protocol defines |
| sitemap.index.child-error | error | spec-required | Every child of a sitemap index must be reachable and parseable |
| sitemap.lastmod.invalid | warning | spec-required | `<lastmod>` must be a W3C Datetime, and must not be in the future |
| sitemap.limits.exceeded | error | spec-required | No single sitemap document may exceed 50,000 entries or 50 MB |
| sitemap.missing | warning | guideline | A site should publish a sitemap |
| sitemap.orphans | warning | guideline | Indexable pages the crawl found should be listed in the sitemap |
| sitemap.unparsable | error | spec-required | A located sitemap must be a well-formed `<urlset>` or `<sitemapindex>` |
Rules goflag will not answer for you
Whether a title describes the page is not something a linter can decide. goflag could fake it — count words, match boilerplate, print a confident verdict — and the result would be unfalsifiable noise. So it states the question, cites what makes it a real requirement, attaches the observed facts, and stops. Ask for them with --advisories; they carry no severity, never count toward the verdict, and are only asked where the subject exists.
| Rule | Severity | Rigor | What it checks |
|---|---|---|---|
| description.accurate | — | guideline | The meta description summarizes this page truthfully |
| hreflang.sitemap-mismatch | — | — | `<head>` alternates advertise a locale the sitemap does not list |
| lang.matches-content | — | spec-required | The declared `lang` is the language the page is actually written in |
| og.image.representative | — | guideline | The `og:image` represents this page and survives the unfurl crop |
| title.descriptive | — | guideline | The `<title>` describes this specific page |
hreflang reciprocity codes
Computed cross-page and reported under missingTranslations.reciprocity rather than through the rule registry, which is why they carry a code instead of a severity. See Translations.
- missing-back-link
hreflang is only honoured when it is reciprocal. A one-way declaration is discarded, so the cluster silently degrades to no cluster at all.
`/fr/pricing` declares an alternate to `/es/precios` but the peer does not link back.
- x-default-missing
`x-default` is what a visitor whose language matches none of yours is sent to. Without it the engine guesses, and it guesses per query.
Page advertises 4 locales but no `hreflang="x-default"`.
- locale.invalid
An invalid tag is not a fallback, it is ignored: underscore instead of hyphen is enough to void the entire alternate.
`hreflang="pt_BR"` is not a valid BCP 47 tag.
What rigor means
Every rule judged on a single page records how authoritative the requirement behind it is, and cites at least one document that backs it. The three site rules do not yet — they run on the contract that predates the catalogue, so the table above shows — for them, and the exported catalogue emits rigor: null rather than a rigor nobody assigned. This is the honest answer to “says who?”: a heuristic is folklore you may knowingly ignore, a spec-required is not. A rule can never claim more authority than its strongest source carries — that is enforced in CI, not left to good intentions.
- spec-required
- A published standard says the page MUST do this. Not a matter of taste.
- spec-recommended
- A standard says SHOULD: expected practice, with room for a deliberate exception.
- vendor-spec
- A de-facto specification a single vendor controls — Open Graph, Google's canonicalization rules. Binding on the consumers that implement it, not on the web.
- guideline
- Documented best practice from a source worth trusting. No specification behind it.
- heuristic
- Industry folklore. Often useful, occasionally wrong, and never something to fix as though a standard demanded it.
Rigor is a fact about the world, so no option changes it. What your build should do about each rule is a separate question, and that is what profiles answer.
heuristicThe length thresholds cite no specification
title.length and description.length cite Google and Moz, and neither is a standard: Google states outright that title length is not a ranking factor. They ship as the display conventions they are, which is why --profile spec-only switches them off entirely rather than merely quieting them.