-
Notifications
You must be signed in to change notification settings - Fork 1
Troubleshooting
Common problems and how to diagnose them. For anything not covered here, open the module's log from Logs in the UI, or open an issue at chodeus/chub/issues with the relevant excerpt.
docker compose logs chubLook for one of these:
Configuration file not found: /config/config.yml — first-run case. Delete the container, make sure the /config bind-mount exists and is writable, start again. CHUB will create a default config.
Configuration validation failed — CHUB prints which field failed. Fix config.yml or remove the bad section and restart — missing sections fall back to defaults.
Address already in use — another process is holding port 8000. Either stop it or change the ports: line in your compose file.
Permission denied on /config — PUID/PGID don't match the owner of the bind-mount directory. Run chown -R <puid>:<pgid> /srv/apps/chub/config on the host.
From inside the host:
curl http://localhost:8000/api/healthIf that works but Docker's healthcheck fails, it's networking on the container — check docker inspect chub and confirm the port binding. A healthcheck timeout can also happen on slow first-launch DB init; raise start_period in your compose file to 90s.
Hit GET /api/auth/status. If it returns { "configured": true } but you don't know the credentials, see Resetting the admin password below.
The login rate limiter fired. Wait 5–10 seconds and retry. If you're hitting it during normal use, you're probably calling POST /api/auth/login in a script on every request — re-use one token (the default expiry is 24 hours; bump auth.token_expiry_hours for automation).
The frontend auto-redirects to the login page on 401. For scripting, just call POST /api/auth/login again to get a fresh token.
Two fixes:
From the command line (Docker Compose):
docker compose run --rm chub python3 main.py --reset-authThen restart CHUB — the first-run form will reappear.
By editing config: stop CHUB, open config/config.yml, delete the entire auth: block, start CHUB again.
From Settings → Instances, click Test on the failing instance. Common causes:
-
Connection refused — URL or port wrong.
http://radarr:7878only works if both containers are on the same Docker network. -
Timeout — the ARR isn't running or there's a firewall between them. Confirm from inside the CHUB container:
docker compose exec chub curl -sS <url>/api/v3/system/status -H 'X-Api-Key: <key>'. - 403 / 401 — wrong API key. Copy it fresh from the ARR's Settings → General → Security.
- "URL blocked by network safety check" — your URL resolves to a cloud-metadata or reserved internal range (a safety check, not a bug). Use a normal routable IP or hostname.
The api field for a Plex instance is the X-Plex-Token, not a Plex login. See Finding a Plex token.
The 6-hour health probe only confirms basic connectivity, not the specific endpoints a module uses. Check the module's run log — it'll show the exact endpoint and status code that failed.
The browser should be receiving server-sent events from /api/modules/events. If it's not, it silently falls back to polling. Common causes:
-
Reverse proxy buffering — Nginx buffers responses by default; that breaks SSE. Add
proxy_buffering off;for the/api/modules/eventslocation. -
Auth expired mid-stream —
EventSourcecan't refresh tokens, so an expired JWT disconnects the stream. Refresh the page. - Gzip on SSE — some proxies compress event streams, which breaks framing. Disable compression for that endpoint.
Cancellation is cooperative: a module has to check a cancel flag in its loop. Most modules (poster_renamerr, poster_cleanarr, labelarr, jduparr, nohl, unmatched_assets, upgradinatorr, renameinatorr, health_checkarr, nestarr, sync_gdrive) stop on the next iteration.
border_replacerr does not check the flag yet — it runs to completion. Cancellation for it is on the roadmap.
plex_maintenance is partial: the PhotoTranscoder cleanup loop checks the flag and stops cleanly, but the three Plex-API tasks (empty_trash, clean_bundles, optimize_db) run to completion because Plex's API has no interrupt. Restart the container if you need to kill one of those mid-run.
Likely causes:
-
dry_run: truein the module config. -
source_dirsempty or wrong. -
destination_dirisn't writable byPUID/PGID. - No matching ARR items — enable
debuglog level and re-run; the log shows per-item match attempts. -
action_type: hardlinkand source/destination are on different filesystems (hardlinks can't cross volumes). Switch tocopyor move both paths to the same volume.
It's hashing your whole library. The first run on a large tree takes hours; every run after that is fast because CHUB remembers what it hashed last time. To stop mid-run, go to Settings → Jobs → Cancel — it'll stop at the next file boundary.
The path-safety guard rejects hash_database, sync_location, gdrive_sa_location, and folder IDs that contain null bytes or start with -. Rewrite the value so it doesn't.
There are two operations in this module; check the right knob.
For the Plex Metadata bloat sweep — the top-level mode value drives it:
-
report— dry-run; lists bloat images without touching anything. -
move— relocates bloat to aPoster Cleanarr Restorefolder. -
remove— deletes bloat outright. -
restore— moves anything in the restore folder back where it came from. -
clear— deletes the restore folder. -
nothing— skips image work entirely.
For the orphan-asset sweep — set orphan_assets_enabled: true AND populate asset_dirs. orphan_assets_mode then takes report / move / remove. If your log says "Library title set is empty…", run poster_renamerr at least once first so the media_cache is populated.
If you're in report for either pass you'll see a list but no file changes — that's by design. Switch to move first (easy to undo) then remove once you trust it.
Also check that plex_path is a filesystem path to the Plex Metadata/ directory as visible from inside the CHUB container — not a URL.
CHUB generates thumbnails on demand and caches them — the first view of a poster is slow, every view after that is instant. To pre-warm a whole library, click Backfill dimensions on the poster stats page and then browse the posters section.
CHUB needs to know each poster's size before the filter can match. Click Backfill dimensions on the poster stats page — it fills in the missing dimensions and the filter starts working.
SQLite allows exactly one writer. You'll see this briefly during concurrent cancel / queue operations; CHUB retries automatically. If it persists, something else is holding a handle — typically a backup script or another container mounting the DB file.
From Settings → Jobs, use the bulk action to purge completed jobs older than 30 days. Health snapshots older than 30 days are pruned automatically on the next 6-hour tick.
general.webhook_secret is set but the caller isn't sending X-Webhook-Secret or ?secret=. Copy the generated URL from Settings → Webhooks — it applies the secret for you.
Almost always a network issue: Sonarr can't reach CHUB. Verify from inside Sonarr's container:
docker compose exec sonarr curl -I http://chub:8000/api/healthLower general.max_logs (default 9 rotated files per module). Old rotations are deleted automatically on the next write.
CHUB automatically redacts things that look like secrets (tokens, API keys, webhook URLs). False positives should be rare — if it scrubbed something that wasn't a secret, open an issue with the pattern it caught.
- Switch the misbehaving module to
log_level: debugand reproduce. - Grab the log excerpt (redacted is fine — CHUB scrubs secrets before writing).
- Open an issue at chodeus/chub/issues with:
- What you expected to happen
- What happened instead
- CHUB version (
GET /api/versionor the footer of the Settings page) - Container or bare-metal install
- The log excerpt