Proof Center · Error Lab
Every refusal, and what to do about it.
A refusal names one cause and its remedy, and is never answered with a 200. A caller fault is a 4xx; a service condition is a 5xx; and a correct refusal — where XRPC declines to hand back something weaker than you asked for — is the system working, not a fault. Search or filter below.
| Code | HTTP | Kind | What it means | What to do |
|---|---|---|---|---|
AUTH_REQUIRED | 401 | Your request | no API key was presented. Send it as Authorization: Bearer <key> | Attach your key. There is no anonymous path to a commercial capability. |
AUTH_INVALID | 401 | Your request | the API key is not one this gateway accepts, or it has been revoked or has expired | Check the key id, and that it has not been rotated or revoked. Revocation takes effect on the next request, with no delaying cache. |
PROJECT_DISABLED | 403 | Your request | the key is valid and its project is suspended. The key does not need replacing | The project, not the key, is the subject. Re-enable it or use another project. |
OUT_OF_SCOPE | 403 | Your request | the key is valid and does not reach this network, capability, transport or environment. Look at the key's scope rather than at your project | Widen the key's scope, or call a capability the key carries. A read-only key never gains broadcast by editing the method set. |
RATE_LIMITED | 429 | Your request | too many requests per second for this project. Retry after the hint | Slow to the sustained rate and retry after the Retry-After hint. This is availability policy, not a weaker answer. |
QUOTA_EXCEEDED | 429 | Your request | this project's allowance for the current window is spent. It resets at the window boundary | Wait for the window to reset, or ask for a higher limit. |
CAPABILITY_NOT_AVAILABLE | 404 | Your request | this build does not serve that capability on that network. See the product catalogue for what it does serve | Read the capability explorer above: it lists exactly what is served, and where. A profile existing is not a capability being available. |
INVALID_REQUEST | 400 | Your request | the request was not one this surface could read | Check the body shape and required fields. An amount in an asset with unknown decimals is refused rather than reinterpreted. |
NO_SAFE_ROUTE | 422 | Correct refusal | no route could produce an answer worth the trust floor you asked for. XRPC will not hand back something weaker under the name of what you asked for | This is the system working. Lower the trust floor if a weaker answer is acceptable, or accept that none is available at the floor you set. |
PARTIAL_COVERAGE | 206 | Correct refusal | there is an answer and it does not cover everything the question implied. What it is missing is stated in coverage | Read the coverage field. A partial answer that says so is not the same as a complete one. |
ENGINE_REFUSED | 422 | Our condition | the engine understood the request and declined it. No source was contacted, so retrying changes nothing -- read detail.engine_said, which says what to change | Read detail.engine_said. Nobody was asked, so ENGINE_REFUSED != UPSTREAM_UNAVAILABLE. |
NETWORK_UNAVAILABLE | 503 | Our condition | XRPC cannot currently serve this network. This is about the network, not the key | Retry with backoff. The condition is the network's, not your request's. |
UPSTREAM_UNAVAILABLE | 502 | Our condition | XRPC asked and the chain sources did not answer | Retry with backoff. A source outage is distinct from an engine refusal. |
INTERNAL_ERROR | 500 | Our condition | something failed inside XRPC | Retry with backoff and, if it persists, send the request_id. A request id is safe to send; a key secret is never needed to investigate. |
Every refusal also carries a request_id, which is
safe to send to support. A key secret is never needed to investigate anything.
The distinction that matters
An engine refusal is not a source outage.
ENGINE_REFUSED (422)
The engine understood
the request and declined it. Nobody was asked, so retrying changes nothing — read
detail.engine_said, which says what to change.
UPSTREAM_UNAVAILABLE (502)
XRPC asked and the chain sources did not answer. This is worth a retry with backoff. Collapsing the two into one 500 is exactly the lie this taxonomy exists to prevent.