Files
LocalAI/docs/content/reference/api-errors.md
T
e715af1def feat(llama-cpp): add slot prompt-cache save and restore API (#12730)
* feat(llama-cpp): add slot prompt-cache save and restore API

Add POST /v1/slots/save and POST /v1/slots/restore. They write one
llama.cpp slot's prompt cache (KV state) to a file and load it back,
so a client can warm a long system prompt in a few hundred
milliseconds instead of re-running prefill. Refs #12685.

The new SlotCache gRPC call posts the same slot save and restore
tasks the llama-server /slots endpoint uses. It is off unless the
model sets the new slot_save_path option, so existing models are not
affected. The /slots monitoring endpoint is not needed here: the
backend has no HTTP server.

The file name comes from the caller, so it is checked twice, in Go
and again in the backend. It must be one path component: no empty
name, "/", "\", "..", NUL, control characters or absolute path. The
resolved path, with symbolic links followed, must be a direct child
of slot_save_path. The routes are admin only because they write
files on the backend host.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(llama-cpp): answer 501 when a backend lacks slot cache

A backend that does not implement the SlotCache rpc returns gRPC
UNIMPLEMENTED. The API passed that text through, so the client saw
"unknown method SlotCache". Map the status to a typed error in
core/backend and return 501 with a fixed message instead. Every other
error path is unchanged.

Make the SlotCache comments in backend.proto backend-neutral: slot is
the backend's state slot, filename must stay inside the save directory,
and an empty model_identity means the backend does not check it. Only
comments change, no field or name.

Add tests that the identity sent is the configured model, and for the
error mapping.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(llama-cpp): issue slot cache IDs on the server

The slot save and restore API let the client pick the file name.
Restore could load any file in slot_save_path, and the symlink check
ran before llama.cpp opened the file.

The backend now issues the name. A save returns a random 128-bit ID
(32 lowercase hex characters, read from /dev/urandom) and never
overwrites an existing file. Files live in a 0700 directory per model,
named from the SHA-256 of the model identity, with a manifest.json
that records each save. The manifest is written atomically and a
corrupt one stops both save and restore.

A restore takes the ID, finds it in the manifest, refuses an entry of
another model, builds the path from the entry and checks with lstat
that it is a plain file of the recorded size. The directory mode is
the main defence against another local user, since llama.cpp still
opens the path itself.

Each model keeps at most 32 saves and the oldest is deleted first. A
file over 8 GiB is deleted after the save, because llama.cpp does not
report the size before it writes. Responses carry no host path.

The HTTP bodies change: save takes {model, slot}, restore takes
{model, slot, id}, and an unknown ID returns 404. In the proto,
SlotCacheRequest.filename and SlotCacheResponse.filename become id.
SlotCache no longer calls checkModelIdentity, which reads a field this
request does not have.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(llama-cpp): copy slot_cache files in prepare.sh

grpc-server.cpp includes slot_cache.h, but prepare.sh copies the helper
headers into llama.cpp/tools/grpc-server/ one by one and skipped it. The
llama-cpp, turboquant and bonsai builds share this step, so they all
failed with "slot_cache.h: No such file or directory".

Copy slot_cache.h and slot_cache_test.cpp, which CMakeLists.txt builds
when LLAMA_GRPC_BUILD_TESTS is on.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* chore(deps): bump LocalAGI to pick up the scheduler start/stop fix

LocalAGI's scheduler could hit a nil pointer in run when Start and Stop
raced. That made the core/services/agentpool tests panic at random and
turned tests-linux red.

Move to mudler/LocalAGI@7aa0c8fea0, the merge of
mudler/LocalAGI#519 ("make Start and Stop safe to call concurrently").
The new module version also adds a few indirect requirements to go.mod
and go.sum.

Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2026-10-17 18:23:02 +02:00

20 KiB

+++ disableToc = false title = "API Error Reference" weight = 26 +++

This page documents the error responses returned by the LocalAI API. LocalAI supports multiple API formats (OpenAI, Anthropic, Open Responses), each with its own error structure.

{{% notice note %}} For backend and runtime failure messages (a model that will not load, could not load model, grpc service not ready, SIGILL, VRAM out of memory, the model-load cooldown 503), rather than API-envelope errors, see {{% relref "reference/runtime-errors" %}}. {{% /notice %}}

Error Response Formats

OpenAI-Compatible Format

Most endpoints return errors using the OpenAI-compatible format:

{
  "error": {
    "code": 400,
    "message": "A human-readable description of the error",
    "type": "invalid_request_error",
    "param": null
  }
}
Field Type Description
code integer|string HTTP status code or error code string
message string Human-readable error description
type string Error category (e.g., invalid_request_error)
param string|null The parameter that caused the error, if applicable

This format is used by: /v1/chat/completions, /v1/completions, /v1/embeddings, /v1/images/generations, /v1/audio/transcriptions, /models, and other OpenAI-compatible endpoints.

Anthropic Format

The /v1/messages endpoint returns errors in Anthropic's format:

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "A human-readable description of the error"
  }
}
Field Type Description
type string Always "error" for error responses
error.type string invalid_request_error or api_error
error.message string Human-readable error description

Open Responses Format

The /v1/responses endpoint returns errors with this structure:

{
  "error": {
    "type": "invalid_request",
    "message": "A human-readable description of the error",
    "code": "",
    "param": "parameter_name"
  }
}
Field Type Description
type string One of: invalid_request, not_found, server_error, model_error, invalid_request_error
message string Human-readable error description
code string Optional error code
param string The parameter that caused the error, if applicable

HTTP Status Codes

Code Meaning When It Occurs
400 Bad Request Invalid input, missing required fields, malformed JSON
401 Unauthorized Missing or invalid API key
404 Not Found Model or resource does not exist
409 Conflict Resource already exists (e.g., duplicate token)
422 Unprocessable Entity Validation failed (e.g., invalid parameter range)
429 Too Many Requests All backends are saturated (per-model max_concurrent or process-wide --max-concurrent-backend-requests ceiling reached). Includes a Retry-After header and type: "rate_limit_error" so OpenAI-compatible clients and harnesses back off automatically
500 Internal Server Error Backend inference failure, unexpected server errors
503 Service Unavailable No healthy node available to serve the model (cluster is full, eviction cannot free a slot, or a node_selector excludes all candidates). Also used during model-load cooldown and while a model is still cold-loading. Retryable

Global Error Handling

Authentication Errors (401)

When authentication is enabled - either via API keys (LOCALAI_API_KEY) or the user auth system (LOCALAI_AUTH=true) - API requests must include valid credentials. Credentials can be provided through:

  • Authorization: Bearer <key> header (API key, user API key, or session ID)
  • x-api-key: <key> header
  • xi-api-key: <key> header
  • session cookie (user auth sessions)
  • token cookie (legacy API keys)

Authorization Errors (403)

When user authentication is enabled, admin-only endpoints (model management, system settings, traces, agents, etc.) return 403 if accessed by a non-admin user. See [Authentication & Authorization]({{%relref "features/authentication" %}}) for the full list of admin-only endpoints.

Example request without a key:

curl http://localhost:8080/v1/models \
  -H "Content-Type: application/json"

Error response:

{
  "error": {
    "code": 401,
    "message": "An authentication key is required",
    "type": "invalid_request_error"
  }
}

The response also includes the header WWW-Authenticate: Bearer.

Request Parsing Errors (400)

All endpoints return a 400 error if the request body cannot be parsed:

{
  "error": {
    "code": 400,
    "message": "failed parsing request body: <details>",
    "type": ""
  }
}

Not Found (404)

Requests to undefined routes return:

{
  "error": {
    "code": 404,
    "message": "Resource not found"
  }
}

Opaque Errors Mode

When LOCALAI_OPAQUE_ERRORS=true is set, all error responses return an empty body with only the HTTP status code. This is a security hardening option that prevents information leaks.

Per-Endpoint Error Scenarios

Chat Completions - POST /v1/chat/completions

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error
# Missing model field
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"role": "user", "content": "hello"}]}'

See also: [Text Generation]({{%relref "features/text-generation" %}})

Completions - POST /v1/completions

Status Cause Example Message
400 Invalid or malformed request body Bad Request
500 Backend inference failure Internal Server Error

Embeddings - POST /v1/embeddings

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
400 No model in the body and no embeddings model configured Bad Request
500 Backend inference failure Internal Server Error

See also: [Embeddings]({{%relref "features/embeddings" %}})

Image Generation - POST /v1/images/generations

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

See also: [Image Generation]({{%relref "features/image-generation" %}})

Image Editing (Inpainting) - POST /v1/images/edits

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Missing image file missing image file
400 Missing mask file missing mask file
500 Storage preparation failure failed to prepare storage

Audio Transcription - POST /v1/audio/transcriptions

Status Cause Example Message
400 Missing file field in form data Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

See also: [Audio to Text]({{%relref "features/audio-to-text" %}})

Text to Speech - POST /v1/audio/speech, POST /tts

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

See also: [Text to Audio]({{%relref "features/text-to-audio" %}})

ElevenLabs TTS - POST /v1/text-to-speech/:voice-id

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

ElevenLabs Sound Generation - POST /v1/sound-generation

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

Reranking - POST /v1/rerank, POST /jina/v1/rerank

Status Cause Example Message
400 Invalid or malformed request body Bad Request
422 top_n less than 1 top_n - should be greater than or equal to 1
500 Backend inference failure Internal Server Error

See also: [Reranker]({{%relref "features/reranker" %}})

Anthropic Messages - POST /v1/messages

Status Cause Error Type Example Message
400 Missing model field invalid_request_error model is required
400 Model not in configuration invalid_request_error model configuration not found
400 Missing or invalid max_tokens invalid_request_error max_tokens is required and must be greater than 0
500 Backend inference failure api_error model inference failed: <details>
500 Prediction failure api_error prediction failed: <details>
# Missing model field
curl http://localhost:8080/v1/messages \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"role": "user", "content": "hello"}], "max_tokens": 100}'
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "model is required"
  }
}

Open Responses - POST /v1/responses

Status Cause Error Type Example Message
400 Missing model field invalid_request model is required
400 Model not in configuration invalid_request model configuration not found
400 Failed to parse input invalid_request failed to parse input: <details>
400 background=true without store=true invalid_request_error background=true requires store=true
404 Previous response not found not_found previous response not found: <id>
500 Backend inference failure model_error model inference failed: <details>
500 Prediction failure model_error prediction failed: <details>
500 Tool execution failure model_error failed to execute tools: <details>
500 MCP configuration error server_error failed to get MCP config: <details>
500 No MCP servers available server_error no working MCP servers found
# Missing model field
curl http://localhost:8080/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "hello"}'
{
  "error": {
    "type": "invalid_request",
    "message": "model is required",
    "code": "",
    "param": ""
  }
}

Open Responses - GET /v1/responses/:id

Status Cause Error Type Example Message
400 Missing response ID invalid_request_error response ID is required
404 Response not found not_found response not found: <id>

Open Responses Events - GET /v1/responses/:id/events

Status Cause Error Type Example Message
400 Missing response ID invalid_request_error response ID is required
400 Response was not created with stream invalid_request_error cannot stream a response that was not created with stream=true
400 Invalid starting_after value invalid_request_error starting_after must be an integer
404 Response not found not_found response not found: <id>
500 Failed to retrieve events server_error failed to get events: <details>

Object Detection - POST /v1/detection

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

See also: [Object Detection]({{%relref "features/object-detection" %}})

Video Generation - POST /v1/video/generations

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

Voice Activity Detection - POST /v1/audio/vad

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request
500 Backend inference failure Internal Server Error

Tokenize - POST /v1/tokenize

Status Cause Example Message
400 Invalid or malformed request body Bad Request
400 Model not found in configuration Bad Request

Slot cache - POST /v1/slots/save, POST /v1/slots/restore

Status Cause Example Message
400 Invalid id on restore, an id sent on save, negative slot, or model not found invalid id: expected 32 lowercase hex characters
404 The id is unknown, or was issued for another model no saved state with this id for this model
400 slot_save_path is not set for the model slot save and restore is disabled for this model: set the slot_save_path option
403 Caller is not an admin (authentication on) Forbidden
412 Backend has save and restore turned off, or the saved file no longer matches its record slot save/restore is disabled
507 The saved state is larger than the 8 GiB limit and was deleted the saved state is larger than the 8589934592 byte limit and was deleted
501 Backend does not support the call slot save and restore is not supported by this model's backend

Models - GET /v1/models, GET /models

Status Cause Example Message
500 Failed to list models Internal Server Error

See also: [Model Gallery]({{%relref "features/model-gallery" %}})

Handling Errors in Client Code

Python (OpenAI SDK)

from openai import OpenAI, APIError

client = OpenAI(base_url="http://localhost:8080/v1", api_key="your-key")

try:
    response = client.chat.completions.create(
        model="my-model",
        messages=[{"role": "user", "content": "hello"}],
    )
except APIError as e:
    print(f"Status: {e.status_code}, Message: {e.message}")

curl

# Check HTTP status code
response=$(curl -s -w "\n%{http_code}" http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "nonexistent", "messages": [{"role": "user", "content": "hi"}]}')

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | head -1)

if [ "$http_code" -ne 200 ]; then
  echo "Error $http_code: $body"
fi
Environment Variable Description
LOCALAI_API_KEY Comma-separated list of valid API keys
LOCALAI_OPAQUE_ERRORS Set to true to hide error details (returns empty body with status code only)
LOCALAI_SUBTLE_KEY_COMPARISON Use constant-time key comparison for timing-attack resistance