> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mudraid.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Interpret verification error codes

> What each error_code means, whose problem it is, and what to do.

When the middleware rejects a request, it returns a single, stable JSON shape. Because the `error_code` never changes wording, you can build dashboards and alerts on it with confidence.

```json theme={null}
{
  "error_code": "MISSING_SCOPE",
  "message": "required scope 'items:write' not present in token"
}
```

## The codes

| Status | error\_code            | Cause                                                                             | Whose problem              |
| ------ | ---------------------- | --------------------------------------------------------------------------------- | -------------------------- |
| 401    | `MISSING_TOKEN`        | No `Authorization: Bearer` header                                                 | Agent                      |
| 401    | `INVALID_TOKEN`        | Malformed JWT or bad signature                                                    | Agent                      |
| 401    | `EXPIRED_TOKEN`        | `exp` is in the past                                                              | Agent (SDK should refresh) |
| 401    | `TOKEN_NOT_YET_VALID`  | `nbf` is in the future                                                            | Clock skew                 |
| 401    | `WRONG_AUDIENCE`       | `aud` doesn't match your `platform_id`                                            | Your config                |
| 401    | `WRONG_ISSUER`         | `iss` isn't an accepted MudraID issuer (default `mudraid-identity`; configurable) | Config, or an attack       |
| 403    | `MISSING_SCOPE`        | Token valid, but lacks the route's scope                                          | Agent not granted it       |
| 404    | `ROUTE_NOT_FOUND`      | No rule for the route, or `skip: true`                                            | By design                  |
| 500    | `JWKS_UNAVAILABLE`     | Couldn't fetch MudraID's keys to verify                                           | Operator / network         |
| 500    | `MIDDLEWARE_NOT_READY` | YAML couldn't be loaded or parsed                                                 | Operator                   |

## How to read them at a glance

Group them by who needs to act:

* **401s — the token is the problem.** Usually the agent isn't sending one, or it expired. With the SDK in use, expiry should be auto-refreshed, so a steady stream of `EXPIRED_TOKEN` is worth investigating (clock skew, a non-SDK caller).
* **403 `MISSING_SCOPE` — authentic but not authorized.** The agent is who it says it is; it just wasn't granted that scope. This is an access decision, not a bug — don't "fix" it by widening scopes reflexively.
* **`WRONG_AUDIENCE` — almost always your config.** The `platform_id` in your YAML doesn't match what MudraID issued tokens for. Re-export the file and redeploy.
* **500s — your side, not the agent's.** `JWKS_UNAVAILABLE` is a connectivity problem reaching MudraID; `MIDDLEWARE_NOT_READY` is a broken YAML. Neither means the agent did anything wrong.

## What to alert on

* A spike in `JWKS_UNAVAILABLE` → connectivity to MudraID is degraded.
* Any `MIDDLEWARE_NOT_READY` → you shipped a bad scopes file; page yourself.
* A spike in `MISSING_SCOPE` from one agent → it's trying to do something it wasn't granted; could be a misconfigured integration or a probe.

## Related

* [Error responses reference](/sdks/middleware/error-responses)
* [Survive key rotation](/guides/platform-operator/key-rotation)
* [Operator playbook](/sdks/middleware/operator-playbook)
