The x402 flow is three steps: the server answers 402 Payment Required with machine-readable payment requirements, the agent pays, the server verifies and serves. When it works, there is nothing to debug.
Then one day your agent pays, the payment settles, and the retry comes back with a fresh 402. Or verification rejects a payment that looks correct. Or the money is on-chain and the resource never arrives.
This is the failure state x402 builders call paid and blocked, and it is worse than an ordinary error because of how the protocol is shaped: x402 is synchronous and terminal. There is no escrow, no result hash, and no on-chain refund path. A failed paid call has no built-in recourse, which means diagnosis is not a nice-to-have — it is the only move you have. This article is the diagnostic order: four failure modes, how to tell them apart, and what fixes each one.
1. The second 402: you paid in the wrong protocol version
Symptom. The payment verifies or settles, you retry the request with proof of payment attached, and the server returns 402 again as if you never paid.
Likely cause. A header version mismatch. x402 v1 servers expect the payment proof in an X-PAYMENT header. v2 servers expect PAYMENT-SIGNATURE. Send the wrong one and the server does not reject your payment — it simply never sees it, so it does the only thing it can do: issue a new 402. From the server's side, your retry is indistinguishable from a first request.
How to verify. Log the exact header your client sent on the retry, and decode the 402 response to see which protocol version the server's payment requirements declare. If the versions differ, you have found it — no amount of re-paying fixes a header the server isn't reading.
The fix. Send the header the server's version expects, and pin the protocol version on both sides of the integration. This failure is silent and repeatable, which makes it the most common cause of "402 again after paying" — and the cheapest to fix once identified.
2. Verification rejects a payment that looks right
Symptom. The server (or its facilitator) refuses the payment outright. No settlement, no resource, and an error that tells you less than you need.
Likely causes. x402 verification is exact, in the literal sense:
- Amount mismatch. The amount must match the requirement exactly. Overpaying or underpaying by 1 wei fails verification. A client that rounds, converts units loosely, or adds a buffer is wrong in a way that looks like "I paid more than asked, why did it fail?"
- Wrong chain ID in the EIP-712 domain. The payment authorization is a signed typed message; if the domain's chain ID doesn't match the network in the payment requirements, the signature is invalid for that requirement no matter how correct everything else is.
- Invalid signature or insufficient funds. A malformed signature fails, and so does a wallet that doesn't hold enough USDC to cover the payment.
- A KYT flag. A payment can be refused on compliance screening even when the cryptography and the balance are both fine.
How to verify. Compare the amount in your payment payload against the requirement in base units, digit for digit. Check the chain ID in the signed domain against the network the 402 specified. Confirm the paying wallet's balance covers the payment. If a facilitator verified the payment, read its actual response — a rejection carries a reason, and guessing past it wastes hours.
The fix. Match the requirement exactly: same amount in base units, same network, same asset. Treat "close enough" as a bug class in payment code, because the verifier does.
3. The facilitator said no — or said nothing
Symptom. Your payment never reaches the server's verifier at all, or comes back rejected from the intermediary.
Likely causes. Most x402 verification runs through a facilitator, and facilitators fail in their own ways: a rejection with a stated reason (CDP's facilitator answers include a rejectedReason — read it before changing anything), facilitator downtime, or a deployment mismatch such as pointing a testnet facilitator at a Base mainnet requirement it doesn't support.
How to verify. Capture the facilitator's raw response, not just your client's summary of it. Confirm the facilitator endpoint in your configuration actually serves the network named in the payment requirements.
The fix. Act on the stated reason. A rejectedReason is the facilitator telling you which of the failure modes in section 2 you are actually in. And log facilitator responses permanently — a rejection you didn't record is a failure you'll have to reproduce from memory.
One related trap, for sellers reading this from the other side: failed payments never settle, so they never appear in settlement data. If you only watch settled payments, rejected attempts are invisible to you. Buyers experience those invisible failures as "I paid and nothing happened."
4. Payment settled, nothing delivered
Symptom. This is the bad one. The payment is settled on-chain. The resource — the report, the data, the completed action — never arrives. There is no pending state to wait out.
Likely cause. An ordering bug on the seller's side, documented in seller postmortems: the server settles the payment before doing the work, the work then fails, and the buyer is left with a settled payment and no output. Because x402 has no escrow and no on-chain refund path, the buyer's only remedy in the standard flow is the seller issuing a manual refund.
How to verify. Assemble the evidence before you contact anyone: the payment requirements you were given, the payment payload you submitted, the settlement transaction, and the server's response to your paid request. You will notice the gap immediately: a transaction hash proves a payment happened. It does not prove who paid it, what it was for, or that you are the party entitled to the undelivered resource. Anyone can copy a hash out of a block explorer.
What fixes it. Honesty first: no client-side tool can force a seller to deliver or refund, and nothing retrofits an escrow into a settled payment. What you can do is arrive with evidence instead of an anecdote — and where a seller supports redemption, prove you are the payer with a signature, not a screenshot of a hash. That distinction is the entire recovery game in x402, and it is where tooling earns its place.
Where callx402 fits: the recovery case
We built callx402 (by Payload, powered by Veyline) for exactly the state this article describes. Two properties shape everything it does:
-
The diagnostics are read-only by design. The six MCP tools —
x402_status,x402_diagnose,x402_evidence,x402_explain,x402_recover,x402_resolve— never charge, execute, retry, or repay. They answer the questions sections 1–4 leave you with: which failure is this, what does the evidence show, and what is the recovery path for it. - There is no key custody, in any version, and the package has zero dependencies. A diagnostic tool has no business holding your keys, and this one structurally can't.
The recovery case is signed redemption. In callx402 1.0.3, redeeming what you paid for requires EIP-191 wallet-signed payer authorization: you sign with the wallet that paid, and the signature — not a transaction hash — is the credential. A tx hash alone is rejected server-side, deliberately, because a hash is public information and proves nothing about who is asking. If you take one practice from this article, take that one: wherever you redeem a paid action, expect to sign, and be suspicious of any flow that treats a bare hash as proof of entitlement.
For agent workflows that would rather call than install, callx402 also exposes nine hosted actions. The package is on npm as callx402@1.0.3, and the same six tools are listed in the official MCP registry.
What callx402 does not do, stated plainly: it does not custody funds, execute trades, or move money on your behalf, and it cannot guarantee a recovery — if a seller settled and vanished, the protocol gives nobody a lever to reverse that. What it gives you is the diagnosis, the evidence assembled in one place, and a redemption path that verifies the right person is asking.
The checklist
When an agent reports paid-and-blocked, work this order before re-paying anything:
-
Which header did the retry carry —
X-PAYMENTorPAYMENT-SIGNATURE— and which version does the server require? - Does the amount match exactly, in base units, against the 402's requirement?
- Does the EIP-712 domain chain ID match the network in the requirements?
-
What did the facilitator actually say — is there a
rejectedReasonon record? - Did it settle? If yes and nothing arrived, stop retrying: gather the requirements, the payload, the transaction, and the response. You are in the evidence-and-redemption case now, not the retry case.
Most paid-and-blocked incidents resolve at step 1 or 2. The rest are only solvable if you kept the evidence — so keep it from the first request, not after the first failure.
The seller-side companion to this article — the failure modes that originate in the server implementation itself — is x402 in production: the failure modes nobody warns you about.
Top comments (10)
@wieedze Yes, and the context rule in your ARP writeup is what would make it work. A single failed response tells callx402 what this one call did, while a verified record of earlier paid and blocked calls to the same endpoint would add whether it keeps happening to other payers in the same situation. A failure caused by something missing on the buyer side should never count against the seller, and keeping that distinction is what turns the record from a reputation score into a diagnostic. When the format is public, we will take a close look.
Thanks, that’s exactly the line I’m trying to hold. The format is already public, and the part closest to callx402 is the outcomes feed, meant to be read before a paid call: arp.intuition.box/docs/x402-feed
A failed line carries one closed reason (arp.intuition.box/docs/lines): missing-key, missing-program, missing-file, not-the-right-tool, or no-delivery for an x402 call that was paid and gave nothing back, with the settlement tx attached.
On your buyer-side point, it goes one step past “never against the seller”: a missing-key failure is set aside for a caller who says it can supply the key, and still shown to one who can’t, since for that caller it’s the useful warning. no-delivery and not-the-right-tool are the ones about the tool itself. And no line moves anything until three different wallets say the same thing.
It’s all on testnet for now, and the feed only holds my own demo records so far (a public fake seller anyone can call), so there’s nothing real to read yet. Does that split match how callx402 sorts a 402 after payment? If you see a buyer-side case these reasons miss, I’d really like to know.
@wieedze Yes, that split matches how we sort it, and setting a missing key failure aside for a caller who can supply the key is a sharper version of the buyer side rule. One case the closed list may miss is a reused or expired payment proof, where the first call settled and the second gets a 402 for presenting the same authorization again. That one belongs to the buyer side too, even though it looks like a fresh paid and blocked call. The feed holding only demo records for now is fine, the reason set is the part worth getting right first.
I agree it belongs on the buyer side. In ARP's case it can't land against the endpoint anyway: a no-delivery line has to name a settlement that checks on chain, and one payment backs one line only. A replayed or expired authorization never settles a second time, so there is nothing to attach the failure to.
What it misses today is a name for it. Right now that buyer would simply write no line, which loses the fact that their own client resent a spent proof. I'll look at a buyer side reason for it, alongside the missing key case.
In your data, does it show up mostly as retries after a timeout, or as clients caching the proof on purpose?
Mostly retries after a timeout, in what we have seen. The first attempt times out before the client sees the settlement result, so it resends the same authorization assuming nothing happened. Deliberate caching does show up in tests and in clients that treat a proof like a reusable token, but the timeout path is the one that bites in real use because it looks like a safe retry.
That's useful, thanks. It also shows me a gap on my side. In the timeout case the first payment did settle, so an agent that never saw the answer would write no-delivery against that settlement, even if the seller did the work and only the response got lost.
So I'll split the two: a seller that answered with nothing stays no-delivery, and a call that timed out before any answer came back gets its own reason on the buyer side, with the resent proof as a second one. That way a client timeout never reads as a seller failure.
In the timeout case, does the seller usually finish the work, so the result could still be claimed with a signed redemption like callx402's, or is it mostly lost?
Mostly the work does finish, in what we have seen. Settlement tends to mean the seller side ran, and when delivery is tied to the payment reference the buyer can come back and claim the result with that reference. The losses are the cases where the result only ever lived in the response that timed out, because then there is nothing left to present.
Seller here (SWARM, a small x402 shop on Base), and your note for sellers in section 3 hit home. Our own sales log only records settled payments, so a buyer whose payment was rejected would never show up anywhere we look, only as a line in the server log. After reading this I’m adding failed paid attempts to our daily report.
On section 4 we ended up on the safe side the hard way: one of our own test purchases got charged for a report that then failed to generate, so we moved settlement to the very end. Now the work runs first and the buyer is only charged if it succeeds.
Out of curiosity, from what callx402 sees: which of the four is most common in practice? My guess would be #1.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.