Troubleshooting#
Use this page when the service does not start, does not answer on port 8011,
or behaves differently than expected in Docker or on the host.
Quick Checks#
Run these first before going deeper:
ss -ltnp | grep 8011
docker compose ps
docker compose logs --tail 100 text-to-speech
For standalone runs:
source .venv/bin/activate
python -c "import fastapi, openvino, soundfile; print('imports-ok')"
python main.py
Service Will Not Start#
Check these in order:
Port
8011is free.ss -ltnp | grep 8011
The active config is valid YAML.
The service loads
config.yaml, then appliesTEXT_TO_SPEECH__...environment overrides. The sameconfig.yamlis used by both standalone and container runs (bind-mounted into the container).Docker is using the expected service directory.
Run
docker compose downanddocker compose upfrom thetext-to-speech/directory that contains this service’sdocker-compose.yml.There is no leftover container name conflict.
If you see an error like:
Conflict. The container name "/text-to-speech" is already in use
remove the old container explicitly:
docker rm -f text-to-speech
First Startup Is Slow#
This is expected.
On first run the service may:
download model artifacts
export models to OpenVINO IR under
models/populate the Hugging Face cache under
.cache/huggingface/
Later starts reuse those cached files and should be much faster.
Model Download Times Out Behind A Proxy#
If model downloads work on the host but time out in the container, export the host proxy variables before starting Compose. The Compose configuration passes both uppercase and lowercase variants to the service:
export HTTP_PROXY="http://proxy.example.com:8080"
export HTTPS_PROXY="$HTTP_PROXY"
export NO_PROXY="localhost,127.0.0.1"
docker compose up -d --force-recreate
docker compose logs -f text-to-speech
Do not commit proxy URLs containing credentials. Configure authenticated proxy values in the shell or another approved secret-management mechanism.
health Endpoint Fails#
For Docker:
docker compose ps
docker compose logs -f text-to-speech
curl --noproxy '*' http://127.0.0.1:8011/health
For standalone:
source .venv/bin/activate
python main.py
curl --noproxy '*' http://127.0.0.1:8011/health
If you are behind a proxy, always use --noproxy '*' for local health checks.
GPU Startup Fails In Docker#
If the container keeps restarting or logs show OpenVINO GPU failures, check the container GPU path before changing the model code.
Typical fatal error:
[GPU] Context was not initialized for 0 device
Check these in order:
/dev/driis exposed to the container.This service already mounts
/dev/dri:/dev/driindocker-compose.yml.The host actually has the GPU device nodes.
ls -l /dev/dri
The container has the right group access for the render node.
On many systems
/dev/dri/renderD*is owned by grouprender, notvideo. This service runs as a non-root user, so it must be given the host render group ID explicitly.Set this in
.env:RENDER_GID=$(stat -c '%g' /dev/dri/render* | head -1)
RENDER_GIDis host-specific. Do not assume992on every machine.Restart the container cleanly.
docker compose down docker rm -f text-to-speech 2>/dev/null || true docker compose up --build
If GPU still fails, isolate whether the problem is Docker permissions or the model/runtime path.
Try the same service with
device: CPUTry a simpler GPU path first, such as SpeechT5 on GPU
Then retry Qwen on GPU
That separation matters because a working Whisper or SpeechT5 GPU path does not guarantee that Qwen GPU initialization will also succeed.
NPU Does Not Behave As Expected#
No TTS model in this service can currently complete a request on NPU, even
though NPU is an accepted device value. Device validation
(utils/device_validation.py::resolve_tts_device) applies to per-request
device selections and to the startup GPU-warmup synthesis — but not to
preload_models(), which loads the configured model directly at startup
without going through this check. A warmup failure after preload is only
logged as a warning and does not stop the service from starting. The
exact error for an actual request depends on the model/runtime:
Kokoro: rejected immediately for per-request selections —
"The configured Kokoro model supports only CPU inference.". Ifmodels.tts.device: NPUis configured instead, Kokoro still loads at startup (the device is ignored) and only a warmup warning is logged.models.tts.runtime: pytorch(non-Kokoro models): rejected immediately —"The PyTorch TTS runtime does not support NPU inference."models.tts.runtime: openvino+ SpeechT5: if no NPU device is visible to OpenVINO, rejected with"Requested TTS device 'NPU' is not visible in this runtime.". If an NPU device is visible, this check passes, but the request then fails during model compilation with a raw OpenVINO compiler error (aReshape/ dynamic-dimension error) — this is a model limitation that device validation does not catch.Qwen3-TTS: fails with a dependency error on startup regardless of device (
CPU,GPU, orNPU) — see Configuration > Qwen3-TTS dependency limitation.Parler-TTS: fails separately, because the
parler-ttspackage is not installed (missing fromrequirements.txt), regardless of device. This is not the Qwen3-TTS/Transformers conflict described above.
See Configuration > NPU for the full per-model breakdown.
Permission Errors On Mounted Folders#
The container runs as UID/GID 1000:1000 (baked into the image).
Model, storage, and Hugging Face cache data are kept in named Docker
volumes (text_to_speech_{models,storage,cache}) initialized with that
ownership, so this rarely fails on a fresh install. If you do hit:
PermissionError: [Errno 13] Permission denied: '/app/text-to-speech/storage/...'
you are most likely reusing volumes that were initialized by a previous run as a different UID (for example by an older root-only run). Reset them:
docker compose down
docker volume rm \
text-to-speech_text_to_speech_models \
text-to-speech_text_to_speech_storage \
text-to-speech_text_to_speech_cache
docker compose up -d
Standalone Import Or Audio Dependency Errors#
If standalone startup fails with missing Python modules, make sure you are using the local virtual environment and that requirements are installed into it.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
If audio loading fails on the host, install libsndfile1:
sudo apt-get update
sudo apt-get install -y libsndfile1