Back to blog
debuggingforensicsx402

Paid but failed: debugging x402 payments on the buy side

6 min read

The x402 failures that hurt aren't the clean ones. A request that never pays is easy — you see the 402 and move on. The expensive, maddening failures are the ones where your agent paid and still didn't get the resource. The money left your wallet; the value didn't arrive. Debugging those is the core of buy-side payment forensics.

The failure modes

Once agents make real x402 payments, a recognizable set of failures shows up:

  • Paid but still 402. The agent pays, retries, and the origin still returns 402 Payment Required — as if it never paid. Settlement lag, a mismatched payment reference, or a seller-side verification bug can all cause it.
  • Paid but the request errors. Payment succeeds, but the retried request returns a 5xx or times out. You paid for an error page.
  • Wrong asset or network. The agent pays in an asset or on a network the server doesn't accept, so the payment is real but not valid for that challenge.
  • Nonce / timing issues. Clock skew, an expired challenge, or a reused reference makes an otherwise-good payment get rejected.
  • Facilitator hiccups. An intermediary that verifies or forwards payment is momentarily down, and the retry fails even though funds moved.

Every one of these has the same signature from your side: money out, resource missing.

Why the buy side is blind by default

Here's the asymmetry that makes this hard. The seller's tooling tells the seller "payment failed" or "payment verified." The buyer — you — sees only the outside of the loop: a challenge, a payment from your wallet, and a retry that didn't work. Your wallet confirms the money left. Nothing tells you why the resource never came.

So teams end up correlating by hand: matching a wallet transfer to an agent log line to a server response, across thousands of attempts. It doesn't scale, and it's exactly when you're bleeding money that you can least afford to do it slowly.

What a correlated attempt timeline looks like

The fix is to treat each x402 interaction as one attempt with correlated legs, not as scattered events:

  • The challenge leg — the initial request and the 402 the server returned (price, asset, network).
  • The payment leg — the on-chain payment your agent made.
  • The retry leg — the request-with-proof and the server's final response (200, still-402, or error), with latency.

Tie those together by a correlation id and the invisible becomes obvious:

attempt  a1b2  domain: data.example.com  /v2/premium
  challenge  402  asset=USDC  network=…       t+0ms
  payment    ok   0.004 USDC                   t+180ms
  retry      402  ← paid, but origin still 402 t+240ms   ⚠ paid_but_failed

At a glance you can see it wasn't a payment problem — the money moved fine — it was a verification problem on the origin. That's a completely different fix (and a completely different conversation with the seller) than "our wallet is out of funds."

Debugging in practice

With correlated attempts you can:

  • Filter to paid-but-failed and payment-error outcomes and see the real failure rate.
  • Group by domain to find the one seller whose verification is flaky.
  • Read the per-leg latency to catch settlement lag before it becomes timeouts.

That's the difference between guessing and knowing — and it only exists if something on the buy side is recording every attempt.

402.report is built for this: non-custodial x402 forensics that surface the paid-but-failed cases sellers never show you. Join the waitlist to debug your agents' payments instead of guessing.