ax-check rule
AXC-F002: Claimed URL could not be verified
A URL returned an access-denied, rate-limit or server error, or timed out, so it could not be verified.
ax-check is a checker being prepared for release. This page documents the rule ahead of that release; see all 50 rules.
| Severity | info |
| 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 |
| Fix in one line | Check the URL by hand; if agents are blocked there, link a page they can read. |
A URL in the file answered with an access-denied response, a rate-limit response or a server error, or it timed out. ax-check could not tell whether the page is fine, so it reports the URL as inconclusive. This is not a defect finding.
What it checks
For each URL, ax-check looks at the HTTP status code that comes back. This rule fires on:
- any status other than success, redirect, 404 or 410, such as 401 or 403 (access denied), 429 (too many requests) or a 5xx (server error),
- an answer of 405 (method not allowed) to GET. The message reads “endpoint rejects GET; this is normal for Streamable HTTP MCP servers”. A server that only accepts POST is not broken, so this is never reported as AXC-F001,
- a timeout, or any other failure to fetch that is not a DNS failure,
- a URL that was skipped because the cap on URLs was reached (raise it with
--max-urls), - an npm or PyPI lookup that failed with anything other than “not found” (for example a 5xx or a network error). The package could not be checked, so it is not reported as missing.
An MCP endpoint is the exception that passes. For a URL whose path ends in /mcp (this also covers /api/mcp), or that is the --mcp target, ax-check sends one POST initialize request when GET is rejected with 405. If the server answers it with a JSON-RPC result, the URL counts as verified and nothing is reported. If it does not, the finding is this rule, and the message adds that the POST initialize did not succeed and why. ax-check sends no other request, and never calls a tool.
A 404, a 410 or a failed DNS lookup is a different case and belongs to AXC-F001.
Why it matters
These responses say very little about the page. A 403 may mean the page needs a login, or that the site blocks automated clients. A 429 means the checker asked too often. A 5xx or a timeout may last only a few minutes. In none of these cases can anyone say the link is wrong.
Reporting them as errors would produce false alarms. ax-check follows the same convention as the agentexperience.tech audit_agent_path diagnostic: a failure to fetch is reported as inconclusive, not as a defect. The finding is still worth reading, because a page that blocks automated clients is also a page an agent cannot read. If the file tells agents to use it, they will hit the same wall.
How to fix
- Open the URL by hand and check that it works.
- If the page is public but blocks automated clients, change the site’s rules, or link to a page that agents can read.
- If the page needs a login on purpose, say so in the file, and do not rely on it as the only source of the information.
- If the server was only briefly down, run the check again later.
Example
Find it:
ax-check drift --online AGENTS.md
Before
## Where to look
- Style rules: https://wiki.invoicekit.dev/style (members only)
- API reference: https://docs.invoicekit.dev/api
The wiki page answers 403 to anyone who is not signed in. ax-check reports it as inconclusive.
After
## Where to look
- Style rules: see `docs/style.md` in this repository
- API reference: https://docs.invoicekit.dev/api
How ax-check detects it
The rule uses the same request as AXC-F001: HEAD first, then GET before judging if HEAD returned 403, 404, 405, 501 or a 5xx, one request at a time per host, a 500 millisecond gap, a 10 second timeout (--timeout) and a cap of 200 URLs (--max-urls). If the final answer is neither success, 404 nor 410, or the request timed out or failed for a reason other than DNS, this rule fires with severity info. A registry lookup for AXC-F003 or AXC-F004 that fails with anything but 404 is reported here too.
For a 405 the final answer after HEAD and GET decides. The message is the same for every URL, because a 405 says only that the method is not accepted: “endpoint rejects GET; this is normal for Streamable HTTP MCP servers (HTTP 405), so it could not be verified”. An endpoint that looks like MCP and fails the POST initialize gets a longer message that includes the reason.
The rule never says the link is broken. It says ax-check could not find out.
Known limits:
- A site that rate-limits after a few requests may return 429 for some URLs and 200 for others in the same run.
- Only URLs that look like MCP endpoints get the POST
initializeprobe. An MCP server at another path passes only when it is the--mcptarget; otherwise it is reported here as inconclusive. - The
--headervalues are sent only to the--mcptarget, never to other URLs. - A site that serves a bot-check page with status 200 is not detected.
Without --online this rule does not run. To silence it, use ax-check drift --online --disable AXC-F002 AGENTS.md, for example when you know a link is private by design.
Sources
- Site guide: Make documentation legible, agentexperience.tech. https://agentexperience.tech/insights/make-documentation-legible/ . Why pages an agent cannot read are a problem even when a person can read them.
- Site guide: Design for recovery, agentexperience.tech. https://agentexperience.tech/insights/design-for-recovery/ . Why a failure should say what happened and what to do next, rather than being treated as one fixed outcome.
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%.
