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

# LLM Gateway error codes

> Reference for errors returned by the Manifest LLM Gateway, with causes and fixes.

When the gateway blocks or rejects a request, the response message starts with a code in square brackets:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
[🦚 Manifest M100] No anthropic API key yet. Add one here: https://app.manifest.build/...
See https://manifest.build/llm-gateway/docs/errors/M100
```

Look up the code below to see what it means and how to fix it.

Except where a section says otherwise, chat and streaming clients receive these codes as an HTTP 200 assistant message carrying the error text, and the HTTP status codes named below apply to non-chat clients (SDKs and tools).

## Authentication (M001–M005)

These fire when the bearer token on `/v1/chat/completions` is missing or wrong. They surface as HTTP 401 to non-chat clients.

| Code                                                                | What                                           |
| ------------------------------------------------------------------- | ---------------------------------------------- |
| [M001: Missing Authorization header](/llm-gateway/docs/llm-gateway/docs/errors/M001) | No `Authorization` header on the request       |
| [M002: Empty Bearer token](/llm-gateway/docs/llm-gateway/docs/errors/M002)           | Header present, token after `Bearer ` is blank |
| [M003: Invalid key format](/llm-gateway/docs/llm-gateway/docs/errors/M003)           | Token doesn't start with `mnfst_`              |
| [M004: Key expired](/llm-gateway/docs/llm-gateway/docs/errors/M004)                  | Key past its expiration date                   |
| [M005: Key not recognized](/llm-gateway/docs/llm-gateway/docs/errors/M005)           | No matching harness for this key               |

## Providers (M100–M102)

Your harness key is fine, but provider credentials are missing or unusable. See [Routing](/llm-gateway/docs/llm-gateway/docs/llm-gateway), [API key providers](/llm-gateway/docs/llm-gateway/docs/providers/api-key-providers), and [Subscription-based providers](/llm-gateway/docs/llm-gateway/docs/providers/subscription-based-providers).

| Code                                                                              | What                                                    |
| --------------------------------------------------------------------------------- | ------------------------------------------------------- |
| [M100: Provider API key missing](/llm-gateway/docs/llm-gateway/docs/errors/M100)                   | Routing picked a provider you haven't connected         |
| [M101: No providers configured](/llm-gateway/docs/llm-gateway/docs/errors/M101)                    | Harness has zero providers connected                    |
| [M102: Provider subscription credentials unusable](/llm-gateway/docs/llm-gateway/docs/errors/M102) | Subscription OAuth/token exists but cannot be refreshed |

## Limits (M200–M204)

You hit a usage cap, rate limit, or Free plan request quota. M200 comes back as an HTTP 200 assistant message for every client: the text rides in the assistant content, not in the HTTP status. M201-M203 surface as HTTP 429 for every client. M204 surfaces as HTTP 402 to non-chat clients because it is a billing plan restriction.

| Code                                                                 | What                                          |
| -------------------------------------------------------------------- | --------------------------------------------- |
| [M200: Usage limit exceeded](/llm-gateway/docs/llm-gateway/docs/errors/M200)          | Cost or token limit you set was crossed       |
| [M201: Per-user rate limit exceeded](/llm-gateway/docs/llm-gateway/docs/errors/M201)  | More than 200 requests/minute from one user   |
| [M202: Per-IP rate limit exceeded](/llm-gateway/docs/llm-gateway/docs/errors/M202)    | More than 500 requests/minute from one IP     |
| [M203: Concurrency limit exceeded](/llm-gateway/docs/llm-gateway/docs/errors/M203)    | More than 10 in-flight requests at once       |
| [M204: Monthly request limit reached](/llm-gateway/docs/llm-gateway/docs/errors/M204) | Free plan monthly request quota was exhausted |

## Request validation and model selection (M300–M303)

M300 means the request body is malformed and surfaces as HTTP 400. M302 and M303 mean the gateway can't reach the model the request asked for. M302 comes back as an HTTP 200 assistant message for every client. M303 surfaces as HTTP 400 to non-chat clients.

| Code                                                                                   | What                                                |
| -------------------------------------------------------------------------------------- | --------------------------------------------------- |
| [M300: Missing messages array](/llm-gateway/docs/llm-gateway/docs/errors/M300)                          | Body has no `messages` array, or it's empty         |
| [M302: Model not available](/llm-gateway/docs/llm-gateway/docs/errors/M302)                             | Explicit model ID is not available for this harness |
| [M303: Local provider unavailable on LLM Gateway Cloud](/llm-gateway/docs/llm-gateway/docs/errors/M303) | Routed to Ollama, LM Studio, or llama.cpp on Cloud  |

<Note>
  M301 is missing from that list on purpose. It capped requests at 1000
  messages, and the cap was removed. If an older self-hosted build still
  returns it, upgrade and the limit goes away.
</Note>

## Server (M500)

The gateway itself broke. Surfaces as HTTP 500.

| Code                                                         | What                                  |
| ------------------------------------------------------------ | ------------------------------------- |
| [M500: Internal server error](/llm-gateway/docs/llm-gateway/docs/errors/M500) | Unhandled error in the proxy pipeline |
