Skip to content

    Development documentation — this describes the current development branch. Documented behavior may not exist in the latest release.

    Common errors

    Text normalization can occasionally drop or rewrite phrases (for example expanding numbers, URLs, or units). Disable it per request:

    {
    "model": "kokoro",
    "input": "Ver. 2.0 ships at 3pm.",
    "voice": "af_heart",
    "normalization_options": { "normalize": false }
    }

    This also affects captioned-speech timestamps, since timestamps track the normalized text. See Extended API.

    If the container starts but cannot use the GPU:

    1. Confirm the NVIDIA Container Toolkit is installed and the runtime is configured.
    2. Confirm you passed --gpus all (Docker) or reserved a GPU (Compose/Kubernetes).
    3. On Linux, if the non-root container user cannot open the GPU devices, add it to the video and render groups:
      • docker run: --group-add video --group-add render
      • Compose: group_add: ["video", "render"]
    4. As a fallback, run on CPU with -e USE_GPU=false to confirm the rest of the stack works. See Hardware profiles.

    If the container logs a model weights not found error and exits, a volume mount is almost certainly shadowing the baked-in weights (for example a bind mount over /app/api). The weights are baked into published images at build time.

    Fix one of:

    • Remove the bind mount over /app/api (the production and local Compose files do not mount source over it).
    • Set DOWNLOAD_MODEL=true to download weights at container start (requires network access).

    This preflight is deliberate: a failed model load exits the container non-zero so orchestrators surface it. See Health and readiness.

    A 503 with Retry-After right after startup means the model is still warming. Poll /ready until it returns 200 before sending synthesis traffic. See Health and readiness.

    For WAV durations that look wrong, or format-specific playback questions, see Audio formats.