ax-check rule
AXC-F001: Claimed URL is broken
A URL in the file returned 404 or 410, or its host did not resolve.
ax-check is a checker being prepared for release. This page documents the rule ahead of that release; see all 50 rules.
| Severity | error |
| Kind | Observed. Depends on the program and environment at run time. |
| Mode | ax-check drift |
| Applies to | Instruction files and manifests |
| Pattern tags | drift, docs-for-agents, llms-txt |
| Fix in one line | Update or remove the link, or restore the page and redirect the old address. |
A URL written in the file answered with 404 or 410, or its host name did not resolve. The file tells an agent to read a page that is no longer there. The agent either fails, or guesses and carries on with less than it needs.
What it checks
ax-check collects every http:// and https:// URL in the file. It sends a HEAD request first and falls back to GET if the server does not answer HEAD well. This rule fires when the answer is 404 (not found), 410 (gone) or when the host name does not resolve in DNS.
Other failures, such as access denied, rate limiting, server errors or timeouts, are not reported here. They are reported as AXC-F002, because they do not prove the page is gone.
Why it matters
Files such as llms.txt exist so that a language model can find a curated list of links (llms.txt proposal). Agent instruction files such as AGENTS.md and SKILL.md work the same way: they point the agent at the pages that explain how to do the work. A dead link silently removes that help. Links go stale as sites are reorganised, and nobody reads the file often enough to notice.
How to fix
- Update the link to the page’s new address.
- If the page moved, restore the old address and redirect it to the new one, so other readers of the old link are not stranded.
- If the page is gone for good, remove the link and the sentence that depends on it.
Example
Find it:
ax-check drift --online llms.txt
Before
# Invoice Kit
> Billing tools for small teams.
## Docs
- [Quick start](https://docs.invoicekit.dev/quick-start): install and first invoice
- [Webhook guide](https://docs.invoicekit.dev/webhooks-v1): events and retries
The webhook guide was renamed, and the old address now returns 404.
After
# Invoice Kit
> Billing tools for small teams.
## Docs
- [Quick start](https://docs.invoicekit.dev/quick-start): install and first invoice
- [Webhook guide](https://docs.invoicekit.dev/webhooks): events and retries
How ax-check detects it
The extraction and the rule logic are deterministic, but the result depends on what the servers that host each URL answer at the time of the run, so the same file can give different findings on another day. JSON and SARIF reports record when and where the check ran. It extracts URLs with a simple pattern, trims trailing punctuation that belongs to the sentence, and requests each distinct URL once. Redirects are followed. It sends HEAD first. Some servers handle HEAD badly, so if the answer is 403, 404, 405, 501 or any 5xx status, ax-check repeats the request as GET before it judges. The final status decides:
- 404 or 410: this rule fires.
- A host name that does not resolve in DNS: this rule fires.
- Success or a redirect (status 200 to 399): no finding.
- Anything else, including a timeout: AXC-F002, because it does not prove the page is gone.
It makes one request at a time per host, leaves a gap of 500 milliseconds between requests to the same host, waits at most 10 seconds for each (change it with --timeout <ms>), and checks at most 200 distinct URLs per run (change it with --max-urls <n>). URLs beyond the cap are reported as AXC-F002, not skipped silently.
It deliberately skips URLs that cannot be checked in a useful way: localhost, loopback addresses (127.*, ::1), 0.0.0.0, the reserved example domains (example.com, example.org, example.net, .example, .test, .invalid, .local), host names with no dot (such as https://host/mcp, a common placeholder), addresses that contain { or < placeholders, and addresses written directly before a placeholder (such as https://example.org/checks/<rule-id>/).
Known limits:
- A page that returns 200 but shows an error message in its body is not detected.
- A DNS failure that is only temporary is reported as a broken host. Run the check again.
To see which URLs would be requested before any request is made, run ax-check drift --online --dry-run llms.txt. Without --online, this rule does not run. Offline mode reports the number of unverified URLs once per file under AXC-F011.
To silence it, run ax-check drift --online --disable AXC-F001 llms.txt. Only do that when the finding does not apply, for example a link you know is served only to signed-in users.
Sources
- Specification: llms.txt proposal. https://llmstxt.org/ . Describes a Markdown file at
/llms.txtthat lists curated links for language models, which is why a broken link in it defeats its purpose. - Site guide: State of llms.txt, agentexperience.tech. https://agentexperience.tech/insights/state-of-llms-txt/ . Background on how llms.txt files are used and maintained.
- Site guide: Make documentation legible, agentexperience.tech. https://agentexperience.tech/insights/make-documentation-legible/ . Why agent-facing documentation needs to stay reachable and current.
Related evidence
Records in the AX evidence register that share a pattern tag with this rule. A shared tag means the record is about the same pattern, not that it tests this rule. Read the evidence class before the number.
- EV-0011: Coding agents mostly read instruction files, not docs sites (Preprint). An observational study of 557 agentic coding sessions (preprint) found that instruction files and working notes made up 60.5% of agents' documentation interactions, against 10.6% for classical technical documentation and 1.3% for API references.
- EV-0012: Compact documentation did not help when the source was present (Preprint). Across two model families and ten repositories, with a positive control, a preprint found that neither compact natural-language documentation nor retrieved context helped coding agents resolve issues better than the issue alone when the source code was present.
- EV-0027: A capable agent skipped the index and guessed the page (Preprint). A preregistered ablation on a 709-page Markdown wiki (preprint) found that a capable tool-using agent never loaded the compact catalogue index, inferring page paths from the question instead, while retrieval-based access kept answer quality non-inferior and cut cost by about a third to over half.
- EV-0029: A warning that names the failing plan redirected agents; a tip did not (Vendor measurement). Microsoft reports that a documentation tip pointing to the right tool got 1 of 5 agent runs to use it, while a warning naming the agent's failing approach ('Manually updating package.json alone will result in build failures') got 5 of 5.
- EV-0030: Adding the context7 MCP server gave no lift; its tools went unused (Vendor measurement). Microsoft reports that adding the context7 MCP server to an anti-hallucination skill gave no meaningful lift on an SPFx upgrade: its tools did not load in 3 of 5 runs and were not called in the other 2, while telling the agent to use CLI for Microsoft 365 raised configuration correctness from 30/80 to 75/80.
- EV-0032: Vendor claim: agents never invoked a docs skill in 56% of eval cases (Vendor claim). Vercel states that in its Next.js 16 evals the docs skill was never invoked in 56% of cases, so the skill matched the 53% pass rate of no docs, while an 8KB docs index in AGENTS.md reached 100%.
