Troubleshooting
This guide covers common issues when running Hassette in Docker and how to resolve them.
Container Won't Start
Check the Logs
Always start by checking the logs:
docker compose logs hassette
For more detail:
docker compose logs --tail=200 hassette
Common Startup Issues
Token Not Set
Symptom: Error about missing or invalid token
Solution: Ensure HASSETTE__TOKEN is set in config/.env:
HASSETTE__TOKEN=your_long_lived_access_token_here
Can't Reach Home Assistant
Symptom: Connection refused or timeout errors
Solutions:
- Verify
base_urlinhassette.tomlis correct - Check network configuration
- Test connectivity from the container:
docker compose exec hassette curl -I http://homeassistant:8123
Permission Errors
Symptom: Permission denied when reading files
Solution: The container runs as user hassette. Ensure mounted files are readable:
chmod -R a+r ./config ./apps
Apps Not Loading
1. Check App Discovery
Verify Hassette can see your app files:
docker compose exec hassette ls -la /apps
2. Verify App Directory Configuration
Ensure apps.directory in hassette.toml matches the container path:
[hassette.apps]
directory = "/apps" # Must match volume mount
If using src/ layout:
environment:
- HASSETTE__APPS__DIRECTORY=/apps/src/my_apps
3. Check for Python Errors
Look for syntax or import errors in the logs:
docker compose logs hassette | grep -i "error\|exception\|traceback"
4. Verify App Configuration
Ensure your app is configured in hassette.toml:
[apps.my_app]
filename = "my_app.py"
class_name = "MyApp"
enabled = true
Dependency Installation Fails
Check Installation Output
Look for installation errors in the logs:
docker compose logs hassette | grep -i "installing\|error\|failed"
Dependency Conflicts
Symptom: Container exits at startup with a DEPENDENCY CONFLICT banner followed by a uv resolver error like:
─────────────────────────────────────────────────────────
DEPENDENCY CONFLICT
Your project's dependencies conflict with this version
of Hassette. This usually means your uv.lock was generated
against a different Hassette version than this image.
To fix: run 'uv lock' locally, commit uv.lock, and restart.
─────────────────────────────────────────────────────────
Because you require yarl==1.20.0 and yarl==1.22.0, we can conclude that
your requirements are unsatisfiable.
Why it happens: Your project's uv.lock was resolved against a different version of Hassette than the Docker image you're running. When the startup script installs your dependencies through Hassette's constraints file, it detects the version mismatch and exits rather than silently downgrading a framework package.
How to fix it:
For project-based installs (pyproject.toml + uv.lock):
# Re-resolve against the current hassette version
uv lock
# Commit the updated lockfile
git add uv.lock
git commit -m "update uv.lock for hassette upgrade"
Then restart the container.
For requirements.txt-based installs: relax any pinned versions that conflict, or check which version range hassette requires:
docker compose exec hassette cat /app/constraints.txt | grep aiohttp # replace aiohttp with your package name
How to prevent it: Pin hassette in your project dependencies to match the image tag you're deploying. For example, if you're using the 0.24.0-py3.13 image:
[project]
dependencies = [
"hassette==0.24.0",
# ... your other deps
]
Re-run uv lock after changing the pin, then commit both files.
pyproject.toml Not Found
Symptom: "No pyproject.toml found" or dependencies not installing
Solution: Check HASSETTE__PROJECT_DIR points to the right location:
environment:
- HASSETTE__PROJECT_DIR=/apps # Must contain pyproject.toml
Verify the file exists:
docker compose exec hassette cat /apps/pyproject.toml
Project Has pyproject.toml But Dependencies Don't Install
Symptom: You have a pyproject.toml but no uv.lock, and the startup log says "run 'uv lock' to generate a lockfile"
Solution: Generate a lockfile locally and commit it:
uv lock
git add uv.lock
git commit -m "add uv.lock"
If you cannot run uv locally, use the requirements.txt approach with HASSETTE__INSTALL_DEPS=1 instead.
requirements.txt Not Found
Symptom: requirements.txt files are not being installed
Solution: Check these in order:
- Confirm
HASSETTE__INSTALL_DEPS=1is set — requirements discovery is disabled by default. Without this variable, no requirements files are scanned.
environment:
- HASSETTE__INSTALL_DEPS=1
-
Verify the filename is exactly
requirements.txt— the startup script only discovers files named exactlyrequirements.txt. Files namedrequirements-dev.txt,requirements_test.txt, or any other variant are ignored. -
Verify the file is under
/configor/appsand is not empty.
Check what the container sees:
docker compose exec hassette fdfind -t f -a --max-depth 5 '^requirements\.txt$' /apps /config
Version Conflicts
Symptom: Package version conflicts during installation
Solutions:
- Use
uv.lockfor consistent, reproducible resolution - For
requirements.txt, relax overly tight version pins - Check the constraints file to see what versions hassette requires:
docker compose exec hassette cat /app/constraints.txt | grep aiohttp # replace aiohttp with your package name
Import Errors at Runtime
If apps fail to import installed packages:
- Verify the package is listed in your dependencies
- Check logs for installation errors at startup
- Ensure
HASSETTE__APPS__DIRECTORYpoints to the correct location
Hassette Restarts Whenever Home Assistant Goes Down
Symptom: Hassette keeps restarting in a loop whenever Home Assistant restarts or goes offline, even though Hassette itself is healthy.
Cause: A Docker healthcheck or an autoheal tool (e.g. willfarrell/autoheal) is pointed at /api/health/ready. That endpoint returns HTTP 503 when Hassette cannot reach Home Assistant, which looks unhealthy to Docker and triggers a restart. The container is marked unhealthy during every HA outage — including routine HA restarts — so autoheal keeps killing and restarting Hassette unnecessarily.
Fix: Point your healthcheck at /api/health/live instead. The liveness endpoint returns 200 whenever the Hassette event loop can respond, regardless of Home Assistant connectivity. Only a true process failure (wedged event loop, container crash, non-zero exit) makes a liveness probe fail.
healthcheck:
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8126/api/health/live"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
If you need a separate traffic-routing signal, use /api/health/ready — but keep it out of any healthcheck that triggers restarts. See Health Endpoints for the full reference.
Health Check Failing
The liveness check queries http://127.0.0.1:8126/api/health/live. This endpoint returns 200 whenever the Hassette process is up and the event loop can respond. It does not check Home Assistant connectivity — HA being down never makes the liveness probe return a non-200 response.
Symptoms
- Container marked as unhealthy
- Container keeps restarting
Solutions
- Check if Hassette is starting successfully:
docker compose logs hassette
- Verify the health service is running:
The health service is enabled by default. Check if it's accessible:
docker compose exec hassette curl -sf http://127.0.0.1:8126/api/health/live
- Check for port conflicts:
Ensure no other service uses port 8126 inside the container.
- Increase start period:
If the container installs dependencies at startup, it may take more than a few seconds before Hassette is ready to respond to health checks. Increase start_period to give it time:
healthcheck:
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8126/api/health/live"]
interval: 30s
timeout: 5s
retries: 3
start_period: 60s
Hot Reload Not Working
Requirements
For hot reload to work:
watch_files = trueinhassette.toml- Files are mounted as volumes (not copied into image)
- If not in dev mode:
allow_reload_in_prod = true
Configuration
[hassette]
watch_files = true
allow_reload_in_prod = true # Only if dev_mode = false
Verify Volume Mounts
Ensure files are mounted, not copied:
volumes:
- ./apps:/apps # Mounted - changes reflected
Import Errors
Package Not Found
Symptom: ModuleNotFoundError: No module named 'xyz'
Solutions:
- Verify the package is in your dependencies:
[project]
dependencies = ["xyz>=1.0.0"]
-
Check installation logs for errors
-
Verify the correct Python environment is active
Hassette Module Not Found
Symptom: ModuleNotFoundError: No module named 'hassette'
Solution: This usually means the virtual environment isn't activated or the Docker image is corrupt. Check the startup logs — the script validates that hassette is importable before doing anything else, and prints a clear error if that import fails. If you see "ERROR: Failed to import hassette — the Docker image may be corrupt", try pulling the image again:
docker compose pull
docker compose up -d
Performance Issues
Slow Container Startup
Causes:
- Installing many dependencies on each start
- No package cache
Solutions:
- Use
uv.lockfor faster resolution (packages are already pinned, no resolution needed) - Mount a persistent cache volume:
volumes:
- uv_cache:/uv_cache
- Pre-build a custom image with dependencies — see Pre-building a Custom Image
High Memory Usage
Solutions:
- Check for memory leaks in your apps
- Limit container memory:
services:
hassette:
# ... other config ...
deploy:
resources:
limits:
memory: 512M
Getting Help
If you can't resolve an issue:
-
Search existing issues: GitHub Issues
-
Collect diagnostic information:
# Container status
docker compose ps
# Full logs
docker compose logs hassette > hassette.log
# Environment
docker compose exec hassette env | grep HASSETTE
# File structure - example uses fdfind to automatically exclude pycache/pyc/etc.
docker compose exec hassette fdfind . /apps /config -t f
- Open a new issue with the diagnostic information
See Also
- Docker Overview — Quick start guide
- Managing Dependencies — Dependency installation details