--- title: "Troubleshooting" description: "Startup refusals, failed model downloads, 503, 409, 413, 421 and 422 responses from decidealot, with the exact message, cause and fix for each." nav_order: 8 --- # Troubleshooting Start with the logs. Decidealot writes JSON lines to stderr, so `docker logs decidealot` shows them. Each line has `time`, `level`, `msg` and structured fields such as `provider`, `status_code` and `request_id`. Set `DECIDEALOT_LOG_LEVEL=DEBUG` for health-check and routing detail. ## Startup refusals Configuration is checked before anything else. An invalid value stops the process with a pydantic `ValidationError` for `Settings` that names the field, and the container exits. | Message | Cause | Fix | | --- | --- | --- | | `DECIDEALOT_CLM_EMBEDDINGS_URL is required when CLM is enabled` | `DECIDEALOT_CLM_ENABLED=true` without a URL. | Set the URL, or set `DECIDEALOT_CLM_ENABLED=auto` or `false`. | | `DECIDEALOT_TYPESAFE_API_KEY is required when Jev is enabled` | `DECIDEALOT_JEV_ENABLED=true` without a key. | Supply the key, or set `DECIDEALOT_JEV_ENABLED=auto` or `false`. | | `at least one provider must be enabled` | Laya and Von are disabled, and neither CLM nor Jev is configured. | Enable a local provider or configure CLM or Jev. | | `DECIDEALOT_DEVICE must match the installed image variant` | `DECIDEALOT_DEVICE` differs from `DECIDEALOT_IMAGE_VARIANT`. | Remove both overrides; each image sets them. Use the `-cuda` image for CUDA. | | `DECIDEALOT_IMAGE_VARIANT must match the installed image variant` | The variant override disagrees with the image. | Remove the override. | | `must be an absolute HTTP URL`, `must not contain credentials`, `must not contain a query or fragment` | `DECIDEALOT_CLM_EMBEDDINGS_URL` is malformed. | Use a plain `http://` or `https://` URL to the `/v1/embeddings` path and put the token in `DECIDEALOT_CLM_EMBEDDINGS_API_KEY`. | | `must be a non-empty comma-separated allowlist` | An MCP allowlist is empty or has an empty entry, such as a trailing comma. | Remove the variable to use the default, or list every value. | Numeric settings outside their range fail the same way with pydantic's own message, such as `Input should be less than or equal to 3`. [Configuration](configuration.md) lists every range. ## The model download fails or never finishes Before it listens, Decidealot prepares every enabled local bundle in turn and logs `preparing local provider bundle` and `local provider bundle prepared` for each. Nothing answers on port `8080` during that time, so `curl` reports a refused connection and Docker reports the container as `starting`. The image healthcheck allows 900 seconds before it counts failures. If preparation fails, Decidealot logs `local provider bundle preparation failed` with the provider and return code, and the process exits. The provider's own error is printed just above it: | Error | Fix | | --- | --- | | `configured model directory must be writable to download missing files` | The host directory mounted at `/models` is not writable by the container user. Create it as the user you pass with `--user`, or fix its ownership. | | `create local model directory for ` or `local model directory for must be readable` | Same cause, at the provider subdirectory. | | `download model repository @` or `download pinned CLM projection head` | Hugging Face could not be reached or refused the download. Check outbound HTTPS from the container, then restart it. Files already downloaded are kept. | | `Laya bundle is missing required files: ...` or `Von model is missing required files: ...` | The download finished without every required file. Delete that provider's subdirectory under the model directory and restart. | | `CLM checkpoint digest does not match the pinned release` | The CLM file on disk is not the pinned release, even after a forced download. Delete `clm/` under the model directory and restart. | A Jev-only deployment downloads nothing and starts in seconds. ## 503 PROVIDER_UNAVAILABLE The `message` field says which case it is. | Message | Cause and fix | | --- | --- | | ` provider did not become ready before the timeout` | The local provider process did not answer its health check within `DECIDEALOT_PROVIDER_START_TIMEOUT_SECONDS`. Loading a model on a slow disk or a busy host can take longer; raise the timeout. | | ` provider stopped before becoming ready` | The provider process exited while loading. The provider's traceback is in the logs just above. Common causes are memory limits (`--memory`) and a missing GPU on the CUDA image. | | `start provider` | The provider command could not be executed. This points at a damaged image; pull it again. | | `the selected provider timed out` | One call took longer than `DECIDEALOT_REQUEST_TIMEOUT_SECONDS`. | | `the selected provider is unavailable` | The provider closed the connection or answered with a `5xx`. For CLM this includes an embeddings endpoint that is down, times out after `DECIDEALOT_CLM_EMBEDDINGS_TIMEOUT_SECONDS`, rejects the request or returns vectors of the wrong width. | | `the selected provider returned an invalid response` | The provider answered with a body that does not match the TypeSafe response shape, or with an unexpected status. For Jev this includes a rejected `DECIDEALOT_TYPESAFE_API_KEY`. | | `the hosted model catalog is unavailable` or `the hosted model catalog is invalid` | TypeSafe's `GET /v1/models` failed, rejected the key, or returned something unexpected. Local selectors keep working. Check the key and TypeSafe's status. | | `local providers are not ready` | The service is shutting down. | ## 409 PROVIDER_BUSY `POST /v1/models/unload` and the `unload_models` tool refuse to unload anything while a local provider is answering a request, with `a local provider is processing a request`. Retry when the request finishes. Decisions never return `409`; they wait for a free slot instead. ## 413 REQUEST_TOO_LARGE The `Content-Length` of the request is above `DECIDEALOT_MAX_REQUEST_BYTES`. Split a large batch or raise the limit, up to `16777216`. ## 422 validation errors The body is the TypeSafe `{"detail": [...]}` envelope, and `loc` points at the field. | `msg` | Fix | | --- | --- | | `Value error, unknown model ''; use a name returned by GET /v1/models` | The selector is misspelled or its provider is disabled. Call `GET /v1/models`. | | `The selected provider does not support this setting` | Laya, Von and Jev take no `config` keys. Remove `config` or send `{}`. | | `Value error, rendered CLM text exceeds the configured UTF-8 byte limit` | A CLM state plus instructions, or one criterion, is longer than `DECIDEALOT_CLM_MAX_TEXT_BYTES`. Shorten it or raise the limit. | | `List should have at most items` | The batch is larger than `DECIDEALOT_MAX_BATCH_REQUESTS`. | ## MCP answers 421 or 403 `421` means the request's `Host` header is not in `DECIDEALOT_MCP_ALLOWED_HOSTS`; `403` means its browser `Origin` is not in `DECIDEALOT_MCP_ALLOWED_ORIGINS`. Both happen behind a proxy or tunnel that uses a public name. Add the exact name as shown in [Expose MCP through a proxy](mcp.md#expose-mcp-through-a-proxy), and keep the loopback defaults in the list. ## 401 UNAUTHORIZED `DECIDEALOT_API_KEY` is set and the request has no `Authorization: Bearer ` header or a different key. MCP clients need the same header in their server configuration. `/health` never needs it.