Skip to content

Troubleshooting

chodeus edited this page Jun 18, 2026 · 7 revisions

🏠 Home › Troubleshooting

Troubleshooting

Find your symptom in the table, jump to the fix. For anything not covered, open the module's log from Logs in the UI or open an issue.

On this page

Symptom finder

Symptom Likely cause Jump to
Container won't start Bad config, port clash, or permissions Container won't start
Docker healthcheck keeps failing Slow first-launch DB init or networking Health check keeps failing
First-run setup page never appears Already configured First-run page doesn't appear
Forgot the admin password Reset the admin password
Login returns 429 Rate limiter fired Login returns 429
Logged out mid-session JWT expired JWT expired mid-session
Instance test fails URL, key, or network Instance test fails
Plex returns 401 Wrong token Plex returns 401
Healthy probe but module run fails Probe is connectivity-only Healthy probe, module fails
Dashboard doesn't update live Reverse-proxy buffering breaks SSE Dashboard doesn't update live
Cancel button doesn't stop a module Cooperative cancellation Cancel doesn't stop a module
poster_renamerr moves nothing Dry-run, paths, or no matches poster_renamerr moves nothing
poster_cleanarr does nothing Wrong mode knob poster_cleanarr does nothing
jduparr runs forever First-run full hash jduparr runs forever
sync_gdrive "invalid path" Path-safety guard sync_gdrive invalid path
Thumbnails slow / low-res filter empty Dimensions not backfilled Posters slow or filter empty
Webhooks return 401 Missing secret header Webhooks return 401
Sonarr "Test connection failed" Sonarr can't reach CHUB Sonarr test fails
chub.db is locked Concurrent writer chub.db is locked
Database is huge Old jobs not purged Database is huge

Startup & container

Container won't start

Read the logs first:

docker compose logs chub

Match the error:

Log line Fix
Configuration file not found: /config/config.yml Make sure the /config bind-mount exists and is writable, then restart — CHUB writes a default config.
Configuration validation failed CHUB names the bad field. Fix it in config.yml or delete the section (missing sections fall back to defaults) and restart.
Address already in use Port 8000 is taken. Stop the other process or change the ports: line in your compose file.
Permission denied on /config PUID/PGID don't match the bind-mount owner. Run chown -R <puid>:<pgid> <config-dir> on the host. See Installation → permissions.

Health check keeps failing

Test the endpoint from the host:

curl http://localhost:8000/api/health
  • Works, but Docker still reports unhealthy — it's container networking. Check docker inspect chub and confirm the port binding.
  • Times out on first launch — DB init is slow. Raise start_period to 90s in your compose healthcheck.

First-run page doesn't appear

Check whether CHUB already has an admin:

curl http://localhost:8000/api/auth/status

If it returns { "configured": true } and you don't have the credentials, reset the admin password.

Login & auth

Reset the admin password

This is the canonical password / login recovery procedure. Pick either method, then reload the web UI — the first-run setup form reappears so you can create a fresh admin account.

Option A — reset command (recommended):

docker compose run --rm chub python3 main.py --reset-auth

This clears the username, password, and JWT secret. Restart the container afterward.

Option B — edit config: stop CHUB, open config/config.yml, delete the entire auth: block, then start CHUB again.

Gotcha: Both methods log out every active session (the JWT secret rotates). Anyone using a saved token must log in again.

Login returns 429

The login rate limiter fired. Wait 5–10 seconds and retry. If it happens during normal use, you're likely calling POST /api/auth/login per request in a script — reuse one token instead (default expiry 24 h; raise auth.token_expiry_hours for automation).

JWT expired mid-session

The frontend auto-redirects to login on a 401. For scripts, call POST /api/auth/login again to get a fresh token.

Instances & connections

First time connecting Radarr / Sonarr / Lidarr / Plex? See First-Run for the full walkthrough. This section is for when a connection that worked stops working.

Instance test fails

From Settings → Instances, click Test on the failing instance:

Result Cause & fix
Connection refused Wrong URL/port. http://radarr:7878 only resolves if both containers share a Docker network.
Timeout ARR is down or a firewall is between them. Confirm from inside CHUB: docker compose exec chub curl -sS <url>/api/v3/system/status -H 'X-Api-Key: <key>'.
401 / 403 Wrong API key. Copy it fresh from the ARR's Settings → General → Security.
"URL blocked by network safety check" Your URL resolves to a reserved/metadata range (SSRF guard, not a bug). Use a normal routable IP or hostname.

Plex returns 401

The api field for a Plex instance is the X-Plex-Token, not your Plex login. See Finding a Plex token.

Healthy probe but a module run fails

The 6-hour health probe checks basic connectivity only, not the specific endpoints a module uses. Open the module's run log — it shows the exact endpoint and status code that failed.

Dashboard doesn't update live

The browser receives server-sent events from /api/modules/events; if that breaks it silently falls back to polling. Common causes behind a reverse proxy:

  • Buffering — Nginx buffers responses by default and breaks SSE. Add proxy_buffering off; for the /api/modules/events location.
  • Gzip on the stream — compression breaks event framing. Disable it for that endpoint.
  • Expired authEventSource can't refresh tokens, so an expired JWT drops the stream. Reload the page.

Modules

Cancel doesn't stop a module

Cancellation is cooperative — a module stops when it next checks the cancel flag.

  • Most modules stop on the next iteration (poster_renamerr, poster_cleanarr, labelarr, jduparr, nohl, unmatched_assets, upgradinatorr, renameinatorr, health_checkarr, nestarr, sync_gdrive).
  • border_replacerr runs to completion — it doesn't check the flag yet.
  • plex_maintenance is partial: PhotoTranscoder cleanup stops cleanly, but empty_trash, clean_bundles, and optimize_db run to completion (Plex's API has no interrupt). Restart the container to kill one mid-run.

poster_renamerr runs but nothing moves

Check, in order:

  1. dry_run: true is set.
  2. source_dirs is empty or wrong.
  3. destination_dir isn't writable by PUID/PGID.
  4. No matching ARR items — set log_level: debug and re-run to see per-item match attempts.
  5. action_type: hardlink with source and destination on different filesystems (hardlinks can't cross volumes). Use copy/move/symlink, or move both paths to one volume.

poster_cleanarr does nothing

Three independent operations live in this module — check the right knob. See Modules → poster_cleanarr for the full reference.

  • Plex metadata bloat sweep — driven by top-level mode: report (dry-run), move, remove, restore, clear, nothing.
  • Orphan-asset sweep — set orphan_assets_enabled: true and populate asset_dirs; orphan_assets_mode takes report / move / remove.
  • Stale-duplicate sweep — set stale_duplicates_enabled: true and populate asset_dirs (shared with orphan); stale_duplicates_mode takes report / move / remove. Also requires media_cache to be populated (run poster_renamerr first).

Gotcha: report lists candidates but changes nothing — that's expected. If the log says "Library title set is empty…" or "No canonical folders found…", run poster_renamerr once first to populate media_cache. Also confirm plex_path is the filesystem path to Plex's Metadata/ directory as seen inside the CHUB container, not a URL.

jduparr runs forever

It's hashing the whole library. The first run on a large tree takes hours; later runs are fast because CHUB remembers what it hashed. To stop, use Settings → Jobs → Cancel — it stops at the next file boundary.

sync_gdrive fails with "invalid path"

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 does neither.

Posters slow or low-res filter empty

CHUB generates and caches thumbnails on demand, and needs each poster's dimensions before the low-resolution filter works. First view of a poster is slow; every view after is instant. Click Backfill dimensions on the poster stats page to pre-warm thumbnails and fill in missing sizes.

Webhooks

Inbound webhook setup, webhook_secret, and retry tuning are documented on the Webhooks page.

Webhooks return 401

general.webhook_secret is set but the caller isn't sending it. Copy the generated URL from Settings → Webhooks — it embeds the secret (?secret=) for you, or send it as the X-Webhook-Secret header.

Sonarr says "Test connection failed"

Almost always Sonarr can't reach CHUB. Verify from inside Sonarr's container:

docker compose exec sonarr curl -I http://chub:8000/api/health

Database

chub.db is locked

SQLite allows one writer at a time. You may see this briefly during concurrent cancel/queue operations; CHUB retries automatically. If it persists, something else holds a handle — usually a backup script or another container mounting the DB file.

Database is huge

From Settings → Jobs, use the bulk action to purge completed jobs older than 30 days. Health snapshots older than 30 days prune automatically on the next 6-hour tick. To shrink the file on disk after a large purge, run a DB vacuum from Settings → System.

Gotcha: Log files can also fill disk. Lower general.max_logs (default 9 rotated files per module); old rotations are deleted on the next write.

Still stuck?

  1. Set the misbehaving module to log_level: debug and reproduce.
  2. Grab the log excerpt (redacted is fine — CHUB scrubs secrets before writing).
  3. Open an issue with:
    • What you expected vs. what happened
    • CHUB version (GET /api/version, or the Settings page footer)
    • Container or bare-metal install
    • The log excerpt

Next: FAQ · Related: Configuration, Modules

Clone this wiki locally