Skip to main content
Most failures return an OpenAI-compatible error body. FastAPI wraps that body in detail:
Rate-limit errors use a top-level error object. See Rate Limits.

HTTP status codes

Common errors

Capability violation (400)

The request does not match the model’s capabilities. Sending document_url to an image-only model, more than one document_url part, or several images to a single-image OCR model all return this.
The same code rejects a parameter that the model does not list in supported_parameters. The check covers temperature, top_p, top_k, min_p, seed, stop, presence_penalty, frequency_penalty, repetition_penalty, logprobs, top_logprobs, tools, and tool_choice. Other unknown fields are ignored.
  • Example: send tools when that list omits it, and param is tools.
  • null: a parameter sent as null counts as not sent.
  • Scope: only parameters you sent are checked. A Gateway default is not.
  • Before you call: read capabilities and supported_parameters on GET /v1/openai/models or the Models page.

Invalid document (400)

document_url is not a valid PDF, is over the size limit, or cannot be decoded.

Invalid media (400)

An image_url or video_url cannot be fetched or decoded.
  • Typical causes: a host that does not resolve, a URL that returns an error, an unsupported container, a corrupt stream, a URL that is not media, or bad base64.
  • Status: 400, not 500.
  • Body: error.type is invalid_request_error, error.code is invalid_media, and error.param names the content part.

Credits exhausted (402)

The caller’s organization has no credit left.

Model not found (404)

model matches no registered model or alias. List them with GET /v1/openai/models.

Rate limit exceeded (429)

A per-tier quota is exhausted. Public OpenAI routes share one budget per caller. Sizes and tiers are on Rate Limits.
  • Anonymous callers: get that message and an X-VLMRun-Upgrade header.
  • Authenticated callers: get Rate limit exceeded: <window>.
  • Every 429: includes Retry-After, set to the longest exhausted window. One wait of that length is enough.
A full queue is also a 429, with Retry-After: 60. Each ingress replica holds up to 256 waiting requests. That cap is capacity, not the quota, and the same call can succeed on retry.

Model unavailable (503)

The deployment is not serving, including during a cold start. Retry-After defaults to 30 seconds. A 504 means the model accepted the request and then missed a deadline.

Key lookup unavailable (503)

The Gateway cannot look the API key up, for example during a database outage. Retry. Do not replace the key.
POST /mcp returns the same 503 with no WWW-Authenticate challenge:

Document inference failed (502)

This status means every page of a document_url request failed. If some pages succeed, the status stays 200: failed pages have status="error", and the rest are returned and billed. A 502 is not a list of those markers, and nothing is billed.
  • Transient failure: the message ends with Please retry. Each page was already tried three times.
  • Deterministic failure: for example an oversized raster. It is not retried, and the message asks you to lower document_dpi or the page size.
  • Streams: once a stream has sent its first chunk, the status cannot change to 502. Those failed pages arrive as error markers.

Model error (502)

The model failed the request. The fault is not in your request, and it is not billed. Retry with backoff.
On a model served by a partner provider, a problem with our provider account is also a 502, a spent provider quota is a 503 with Retry-After, and a provider timeout is a 504. A 4xx means your request.

Internal server error (500)

A fault in the Gateway itself returns a sanitized body, with no stack trace or internal path.
  • Every response includes an x-request-id header.
  • On a sanitized 500, that same id is error.request_id.
  • Send either to support@vlm.run.
Send an x-request-id request header to set your own correlation id. The Gateway echoes it. If you omit the header, the Gateway mints one.

Inference timeout (504)

Each model has two deadlines. The Gateway aborts the request when either passes. Both are set per model in the catalog. They can change, and they are not an SLA. qwen/qwen3.8-27b and baidu/unlimited-ocr allow 60 seconds to the first token. A 64-image or 32-page prompt can spend more than 30 seconds prefilling before a token exists. A first-token timeout is a 504 on the streaming path too. The Gateway reads the first chunk before it starts the response, so you do not get an empty 200.
  • Routed model: the message starts with the provider in brackets, for example [fireworks] Model ... returned no output within 30s.
  • Non-streaming: if the Gateway aborts the request, there is no partial result.
  • No model named: a request that names no model, including an embeddings call, uses one 270 second window.
  • Retry: a ttft_timeout often clears once the deployment has scaled, so retry with backoff.
  • Client timeout: keep it above the model’s total deadline. An OpenAI SDK timeout= below that fails first, with the SDK’s own error.
  • Less idle time: smaller payloads, and stream=true, leave less idle time before the first token.

Getting help

Send support@vlm.run the x-request-id (or error.request_id on a sanitized 500), the status and body, and the model plus the content part types you sent. Retry behavior is on Rate Limits and the Chat Completions API reference.