LIVE
Nirium← Home
Back to blog
Settlement6 min read

Mainnet x402 Was Down for 32 Days: Don't Trust Us, Verify the Fix

Sep 11, 2026 Stellar mainnet 32 days down

Every payment product built on a standard it doesn't fully control eventually meets the same test: what happens when the thing you depend on breaks, and it isn't your code? For 32 days, mainnet x402 payments against Nirium's endpoints failed on every attempt — not from a bug we wrote, but from a misconfiguration inside a facilitator we don't operate and can't patch ourselves. This post is the arc end to end: what broke, how we proved it wasn't ours, how it got fixed, and what we shipped so the next outage doesn't need an outside report to be noticed.

Nothing here is a summary you have to take on faith. Every transaction hash, GitHub comment, and file below is a link — go check it.

The fact, in plain terms

Starting around August 10, 2026, every mainnet x402 settlement against Nirium's paid endpoints — and against every other integrator using the same hosted facilitator — began failing with `unexpected_verify_error`, a catch-all for an unhandled exception inside the facilitator's own `verify()` call. Not a rejected payment: the facilitator never got far enough to evaluate one. Isolation testing that day, and every day after, showed the same pattern: the identical client and payload settled cleanly on testnet, and failed the same way on mainnet, every single time.

We filed OpenZeppelin/relayer-plugin-x402-facilitator#47 on August 19. Three independent integrators — us, AgentLedger, and a third party — converged on the exact same finding across a month of silence on two official OpenZeppelin channels. What actually broke it open wasn't the thread or a support-forum post: it was tagging, by handle and directly, the two maintainers we'd verified were still active elsewhere in the org. One replied within a day.

The root cause, once posted: the hosted pubnet facilitator instance was pointed at a stale RPC URL, so `verify()` threw before it ever reached the payload. We retested the same afternoon with a real settlement against our own mainnet endpoint — clean `200`, confirmed on Horizon. A second, fully independent team ran the identical test the next day, with the same result. Two teams, two payments, two different days, one root cause:

Why this matters, beyond this one outage

Every payment product built on x402 — ours included — depends on a facilitator it doesn't operate. That dependency is real, not theoretical, and pretending otherwise doesn't make an outage less likely. What actually changes the outcome is whether the failure gets found, diagnosed with the same discipline as a bug in your own code, and made visible instead of quietly retried into invisibility.

The right response to depending on infrastructure you don't control isn't to hide when it breaks — it's to instrument it, diagnose it with method, and leave permanent visibility behind so the next failure doesn't need an outside report to be noticed.

What this means, actor by actor

This isn't one story — it's a different, specific claim for each party near it. Here's what each one can actually check.

For OpenZeppelin

A hosted facilitator carries real operational weight — every integrator's paid traffic routes through it, and a silent misconfiguration on their side is invisible from ours until someone reports it from outside. Once tagged directly, the actual fix (correcting the pubnet RPC URL) landed within two days, and it's held under two independent teams' real settlements since. That outcome matters more than how long the silence lasted.

For Fernando / AgentLedger

His own mainnet payment hit this exact outage on September 4, blocked by something entirely outside his control or ours. He stayed in the thread, retried the day after the fix shipped, and posted his own independent confirmation — a second real settlement, a different account, the same clean result. That's stronger evidence than any single team re-testing its own fix.

For Stellar as an ecosystem

This ran entirely on mainnet, against real infrastructure, with real fee-sponsored USDC settlements — not a testnet demo standing in for one. A facilitator outage affecting a whole ecosystem is exactly the kind of failure that's easy to describe in the abstract and hard to prove was real; this post exists so nobody has to take that part on faith either.

For Nirium's clients and integrators

The mainnet paid path is reliable again, confirmed by two separate teams on two separate days — not just our own word that it's fixed. Nothing changes on the integration side: the same client, the same endpoints, the same header. If it failed for you during this window, it wasn't your integration.

For Nirium

We shipped a server-side logging hook mid-outage — `onAfterVerify`/`onVerifyFailure` on the facilitator client, writing every rejection reason and payer address into our own logs instead of only being visible from outside. It stays in place permanently, not as a workaround for this specific bug: it's the difference between finding the next facilitator regression ourselves and waiting for another integrator to report it first.

Go check it

Every link above resolves to something you don't have to take our word for — a live block explorer, a GitHub issue thread, our own devlog entry with the dates and root cause spelled out. Decode the transactions. Read the thread. If something here doesn't hold up the way this post says it does, that's worth knowing — for you and for us.

Where we are

x402 and MPP Charge run live on both testnet and mainnet today — the same endpoints, the same client, the same header, nothing changed by this incident except that a facilitator-side failure now lands in our own logs the moment it happens instead of after someone else notices first.