AI Skill Certs
Tool Design & MCP Integration·Task 2.2·Bloom: analyse·Difficulty 4/5·9 min read·Updated 2026-06-07

Access Failure vs Empty Result: The Agent Retry Trap

Implement structured error responses for MCP tools

SUBy Solomon UdohReviewed by Solomon UdohAI-assisted · human-reviewed
In short
An access failure means the tool could not reach its data source, due to a timeout or auth problem, and may be worth retrying. A valid empty result means the source was queried successfully and genuinely returned no matches, which is a definitive answer. Confusing the two makes an agent retry a real "no match" or quietly trust a hidden outage.

Access failure vs empty result, precisely

The distinction between an access failure vs empty result is the most error-prone judgement in Task Statement 2.2, which is why this knowledge point sits at the analyse level and at difficulty four. An access failure means the tool could not reach its data source at all: the request timed out, authentication was refused, the connection dropped. The tool does not know the answer, because it never got one. A valid empty result is the opposite situation: the tool reached the source, ran the query successfully, and the truthful answer is "there is nothing here." Both can come back looking like "no data," and treating them the same way breaks an agent in two different directions.

Holding the access failure vs empty result boundary clearly is what separates a reliable agent from a confidently wrong one. One outcome means "I do not know yet, ask again." The other means "I checked, and the answer is no." Those are not interchangeable, and the recovery logic that flows from each is opposite.

Why the two collapse into one bug

The reason this is hard is camouflage. A poorly built tool that crashes mid-query can still return a normal-looking response: an HTTP 200 with an empty body, or a result list of length zero. To the agent, that is indistinguishable from a genuine "no matches." The failure has put on the costume of an empty result. This is the well-known false-positive problem where a 200 status hides an error in the body, and it is precisely what turns an outage into a phantom answer.

When that happens, the agent draws the worst possible conclusion. An access failure dressed as an empty result makes the agent announce that something does not exist when it was simply never checked. A customer's account is reported missing during a database blip; a research subagent reports no sources when its search endpoint was down. The bug is not in the agent's reasoning. It reasoned correctly about bad data. The bug is that the tool failed to keep the two outcomes distinct.

The mirror-image failure

The trap runs both ways, and the less obvious direction is just as damaging. If a valid empty result is mistakenly modelled as a failure, the agent retries a definitive answer. It calls the lookup, gets "no account found," treats that as something to recover from, and tries again. And again. The classic anti-pattern is an agent that retries three times and then escalates to a human, when the answer all along was a perfectly correct "this account does not exist." The retries cost latency and tokens, and the escalation wastes a person's time on a question that was already answered.

So the cost of confusing the two is symmetric. Mislabel a failure as empty, and the agent reports false absence. Mislabel empty as a failure, and the agent loops and escalates on a settled fact. Either way the root cause is the same missing distinction at the tool boundary.

Access failure
source not reached; may retry
Empty result
source reached; no matches; final
200 + empty
the camouflage to design against

Designing tools that keep the two apart

The fix lives in the tool, not the prompt. A well-built tool returns a valid empty result as an ordinary success, an explicit empty set the agent can accept, and returns an access failure with its error flag set and a description that says the source was unreachable. The MCP error contract makes this clean: a true no-match is a normal result with the error flag false, while an outage is a result with the flag true. The boolean draws the line the agent needs.

Concretely, that means catching transport and auth exceptions and converting them into explicit failures, rather than letting them fall through as empty responses. It also means making "found nothing" a first-class, unambiguous success rather than an absence the agent has to interpret. When the tool is honest about which outcome occurred, the agent's job becomes trivial; when the tool blurs them, no amount of prompting reliably un-blurs them.

One query, two honest outcomes
Loading diagram...
Reaching the source is a separate question from whether the source held anything.

Worked example

A support agent looks up a caller's account with a lookup_customer tool while the customer database is intermittently unavailable.

The caller gives an account number. The agent calls lookup_customer. Two very different things can happen, and the tool must report them differently.

In the first case the database is up, the query runs, and there is genuinely no account with that number, the caller misremembered it. The tool returns a normal success with an empty result. The agent accepts this as final: "I could not find an account with that number; can you double-check it?" No retry, because the answer is real.

In the second case the database is mid-outage and the connection times out. A badly built tool would return an empty list and the agent would say the same sentence, falsely telling a real customer their account does not exist. The correctly built tool instead returns a failure with the error flag set and the description "customer database unreachable (timeout)." Now the agent says something honest: "I am having trouble reaching our records right now," and it retries shortly or escalates if the outage persists.

The two conversations diverge entirely, and the only thing that determined which one the customer experienced is whether the tool kept access failure and empty result distinct. The agent reasoned correctly in both cases; the tool's honesty is what made correct reasoning possible.

Common misreadings to avoid

Misconception

An empty result is a kind of failure, so the agent should retry it a few times before giving up.

What's actually true

A valid empty result is a successful query that truly found nothing; it is a final answer, not a failure. Retrying it just repeats the same definitive no, adding latency and often a needless escalation. Retries belong to access failures, where reaching the source might succeed later.

Misconception

If a tool returns HTTP 200 with no data, the agent can safely conclude there is no matching data.

What's actually true

A 200 with an empty body can hide an access failure, such as a crash or rate-limit response slipped into a successful-looking envelope. The agent then reports false absence. Tools must convert unreachable-source conditions into explicit failures rather than letting them masquerade as empty results.

The signal lives in "was the source reached", not "was data returned"

The cleanest way to keep the two outcomes apart is to anchor on the right question. The instinctive question is "did the tool return any data?", but that question cannot distinguish a real no-match from an outage, because both can return nothing. The question that actually separates them is "did the tool reach and successfully query its data source?" An access failure answers no; a valid empty result answers yes. Reaching the source is a different fact from finding something in it, and a well-built tool reports those two facts independently.

Once you frame it that way, the design follows naturally. The tool first establishes whether it got to the source at all. Only if it did does it then report how many matches the source held, including zero. By separating reachability from result count, the tool never has to collapse "I could not look" and "I looked and found nothing" into the same empty response. The agent receives two distinct shapes for two distinct truths.

Why prompting cannot reliably fix a blurred tool

A frequent wrong instinct is to patch this at the prompt: instruct the agent to "double-check whether an empty result might be an error." That guidance cannot work reliably, because if the tool returns an identical-looking empty success for both an outage and a genuine no-match, the agent has no signal to act on. You are asking the model to distinguish two inputs that are, on the wire, the same input. No amount of prompt wording recovers information the tool threw away.

This is why the knowledge point is firmly about tool design, not prompt design. The distinction must be preserved at the boundary where the failure is actually known, inside the tool, which can see the timeout or the auth rejection. Move the responsibility downstream to the prompt and you have moved it past the only place where the truth was still available. The agent can reason brilliantly and still be wrong, because it is reasoning about a result that already lost the distinction.

A two-question test for any ambiguous result

When you meet an ambiguous outcome, in an exam stem or a real incident, run two questions in order. First: did the tool reach its data source? If you cannot tell from the result, that itself is the bug, because the result should make it obvious. Second, only if the source was reached: did the source contain any matching records? A "no" to the first question is an access failure to retry or escalate; a "no" to the second is a valid empty result to accept as final.

The order matters. Asking about matches before confirming the source was reached is how the trap springs, because a failure with zero data sails through the second question looking like a clean no-match. Confirming reachability first closes that gap. This two-question test is the analytical core of the knowledge point, and it generalises to any tool that queries an external system on the agent's behalf.

What this costs in the customer-support scenario

The reason this sits at difficulty four is the human cost when it goes wrong, vividly so in the customer-support scenario. A customer told their account does not exist during a database blip does not experience a minor technical glitch; they experience being erased. Trust evaporates fast when a system confidently denies something true. Conversely, an agent that loops and escalates on a genuine "no such order" wastes the customer's time and a human agent's attention on a question that was already answered correctly.

Both failures are avoidable, and both trace to the same root: a tool that did not keep access failure and empty result distinct. Getting this one right is disproportionately valuable precisely because the cost of getting it wrong lands directly on a real person in a moment when they are already asking for help.

Status codes and retry signals at the wire level

It helps to see how the distinction looks in HTTP terms, because a tool usually sits on top of a REST or RPC call. A genuine empty result should ride on a success status, a 200 with an explicit empty set or a resultCount of zero, not a 404. Reserving 404 for "the source had no match" is the classic mistake the REST community warns against: an empty list is a successful query, so a 404 blurs "nothing found" into "endpoint missing," which is exactly the camouflage this page exists to prevent. Keep "no data" on a success envelope and keep "could not reach the source" on an error envelope.

When the failure genuinely is an access problem, retry only on a transient signal, and prefer the provider's own hints over a blanket retry. Anthropic's API documents this directly: it exposes an x-should-retry header to indicate whether a 500 is worth retrying, asks clients to honour retry-after on a 429 before backing off, and flags 502, 503, 504, and 529 as transient conditions to retry with capped exponential backoff. A 404, by contrast, means the resource is gone or never existed, so the correct move is to stop calling it rather than retry.

Carrying these signals through to the agent is what lets it act correctly. A tool that surfaces "transient, retry after 30s" lets the agent wait and try again; a tool that surfaces "resource not found" tells the agent to take a different path entirely. The wire-level detail matters because it is the layer where the access-versus-empty boundary is either preserved honestly or quietly destroyed before the agent ever sees it.

How this is tested

Because this is an analyse-level knowledge point, exam items put you inside an ambiguous outcome and ask you to diagnose it. A stem might describe an agent that escalates after retrying a "customer not found" three times, and ask what went wrong, the answer is that a valid empty result was wrongly treated as a retryable failure. Another might describe an agent reporting "no records" during a known outage, where the fault is an access failure disguised as an empty result. In both, the assessed skill is separating "the source was not reached" from "the source held nothing," and routing each to its correct response.

Check your understanding

A support agent calls a tool to find a customer's open tickets. The ticketing service is down, but the tool catches the timeout and returns an empty list with a success status. What does the agent most likely do, and why is it wrong?

People also ask

What is the difference between an access failure and an empty result?
An access failure means the tool never reached its data source (timeout, auth error), so the answer is unknown and a retry may help. An empty result means the source was queried and truly has no matches, which is a final answer.
Should an agent retry an empty result?
No. A valid empty result is a successful query that found nothing, so retrying repeats the same definitive no. Retries belong to access failures, where reaching the source might succeed on a later attempt.
Why is an empty result dangerous to model?
Because an access failure can masquerade as one. If a crash returns a 200 with no data, the agent reads "nothing found" instead of "lookup failed" and confidently reports absence that is not real.

Watch and learn

Official Anthropic Academy lessons first, then hand-picked walkthroughs. Videos load only when you press play.

AI Engineer

Building Agents with Model Context Protocol - Full Workshop with Mahesh Murag of Anthropic

Why watch: Anthropic's own MCP lead explains how MCP tools return results and signal failures, the foundation for distinguishing a genuine access failure from a successful query that simply returns no matches.

More videos for this concept

References & primary sources

Adaptive study

Master this concept with Archie

Practice it inside an adaptive study session. Archie, your Socratic AI tutor, tracks your mastery with Bayesian Knowledge Tracing and schedules the perfect next review.

Start studying