Troubleshooting
Start with these two, in this order — they answer most questions without guessing:
subtrace config show # the configuration actually in effect, secrets masked
subtrace status # what the database believes, and today's quota useAdd --log-level debug to any command for the reasoning behind a skip.
“cannot write to library root”
error: cannot write to library root /media/Movies: permission denied
subtrace writes subtitle files next to the videos, so the process needs write access there.fetch probes every root before doing any work, so this fails immediately
rather than thousands of files in. Causes, most common first:
- The media mount is read-only. Media servers usually mount libraries
:ro; subtrace cannot. Remove the:ro. PUID/PGIDdo not match the files’ owner. Check withls -ln /mnt/media/Movieson the host and compare the numeric uid/gid.- The directory genuinely denies writes to that user.
chmod/chownon the host.
--dry-run skips the probe, which is a quick way to confirm the rest of the
setup is fine while you sort permissions out.
Everything comes back not_found
Look at what is being asked for:
subtrace fetch --limit 1 --log-level debugIf the folder names carry no {tmdb-…} / {imdb-…} / {tvdb-…} id, subtrace
falls back to a title-and-year search, and misses are expected. Renaming to the
Plex/TRaSH convention is the real fix — Radarr and Sonarr do it automatically.
See Naming and matching.
Also worth checking:
- The language exists for that title. A less common
languagesentry will legitimately be missing for a lot of the catalogue. - Only one provider is actually configured.
subtrace statuslists the enabled providers; one missing an API key is skipped silently.
Nothing is downloading, but nothing is failing either
Almost always the daily cap:
downloads today
opensubtitles 100 / 100
subdl 100 / 100Once every provider is parked, remaining items are left pending — deliberately
not marked failed, so they are not charged an attempt. The counter is keyed by
UTC date, so it resets at midnight UTC, not at your local midnight.
The other possibility is that the batch is empty because everything eligible is
in backoff: not_found items wait run.retry_after_hours (default 168h). Force
a retry with subtrace fetch --force.
Subtitles land but Plex/Jellyfin does not show them
- Ownership. Written files are chown’d to
PUID:PGIDonly when subtrace is running as root. Outside the container, files are owned by whoever ran it.ls -lnext to the video and compare with the media server’s user. - Naming.
subtitles.namingmust produce something your server recognizes. The default{basename}.{lang}.srtis what Plex auto-detects. - Scan timing. Without the Plex integration, the server picks them up on its own next scan.
The Plex refresh does nothing
Debug logs show:
plex refresh matched no library section (path mapping differs?)Sections are matched by filesystem path. A container that sees /media/Movies
while Plex sees /data/movies will never match. Mount the library at the same
path in both.
The scan count looks wrong
Way too high — usually double-counting from a NAS metadata directory.
@eaDir is in ignore_dirs by default; if you overrode that list, put it back.
Also check min_file_size_mb (default 50): sample files and clips inflate
counts when it is set to 0.
Way too low — check that scan.video_extensions covers your container
formats, and that an over-broad ignore pattern is not eating real files. Remember
* does not cross /, so */Extras/* matches nothing while **/Extras/**
works. See Ignore patterns.
Files that already have subtitles are counted as missing — subtrace looks for sidecars only. Embedded tracks inside the container are not examined.
“not a valid subtitle file”
not a valid subtitle file: provider returned an HTML page
not a valid subtitle file: no subtitle timecodes found
not a valid subtitle file: empty responseThis is working as intended: the download was rejected before it could reach the disk. subtrace tries the next candidate. Seeing it constantly for one provider usually means a credential problem — an expired login often comes back as an HTML page rather than a proper error.
“no config file found”
error: no config file found (looked in: subtrace.toml, /home/you/.config/subtrace/subtrace.toml, /config/subtrace.toml)
Write one with: subtrace config init > subtrace.tomlIn a container this means /config is not mounted, or the file inside it is not
named subtrace.toml. Point at it explicitly with SUBTRACE_CONFIG if you keep
it elsewhere.
Database questions
run.db_path defaults to /config/subtrace.db when /config exists, and
~/.local/share/subtrace/subtrace.db otherwise. It is a plain SQLite file:
sqlite3 "$(subtrace config show | awk '/^database/{print $2}')" \
"select status, count(*) from items group by status;"Deleting it loses history only — the next scan rebuilds everything from disk,
and files that already have sidecars go straight to have. The one thing you
lose is today’s quota counter, so subtrace may exceed the provider’s real cap
for that day.
Reporting a bug
Include your folder layout (one representative path) and a subtrace config show
dump — secrets are already masked. Issues:
https://github.com/alexraskin/subtrace/issues.