Disclaimer: This documentation is provided for convenience and may contain errors. Always verify information against the official Kodi and provider documentation. Report issues.
Fastmail
Home / Troubleshooting

Troubleshooting & known issues

Recipes for symptoms observed in production. Each entry follows the form symptomcausefixreference into the docs.

Database & sync

"Packet sequence number wrong - got 2 expected 1"

Cause: two provider-sync daemon threads sharing the same pymysql connection. The MySQL protocol is per-connection; interleaved packets from two threads corrupt each other.

Fix: each worker thread owns its own connection. The implementing code in library_sync._get_db uses threading.local() + a guard that only the main thread can fall back to the module-level _sync_db. Don't break the threading.main_thread() check — any path that lets a worker thread pick up _sync_db reintroduces the corruption.

"'NoneType' object has no attribute 'read'"

Cause: same thing from the other thread's perspective — its socket reader got closed out from under it by the other thread's ping() failure.

Fix: same — per-thread connections.

Empty/un-prefixed duplicate tvshow rows appearing

Cause: Kodi's TMDB scanner recursing into the addon's plugin URL path row, or into a disk-folder path row that hasn't been marked exclude=1.

Fix: the sync's path reconciliation (_ensure_path in library_sync) creates the series root with exclude=1 on the first run, so no new duplicates should appear going forward. Remove any already-created duplicate rows (rows the scanner made, without the [PROVIDER] prefix) and let the next sync rebuild the prefixed ones — the library sync is insert-only, so correcting wrong rows means deleting them and letting the scheduler rebuild.

TV show row with 0 episodes despite a real TMDb match

Cause: the provider's list_episodes call threw an exception (transient HTTP failure or partial outage). The sync insert guard skips shows with no episodes, but if the fetch fails the show stays out of the library until the next sync slot.

Fix: _sync_series fetches episodes before calling _insert_tvshow. If the fetch fails the show is simply skipped on this run and retried on the next scheduled pass.

Empty show rows in DB with no episodes

Symptom: old tvshow rows visible in Kodi's library with poster and metadata but zero episodes underneath.

Cause: the rows were inserted by a sync run whose subsequent episode fetch failed partway through — the show exists but the episode rows were never written.

Fix: the sync no longer inserts empty tvshow rows (current _sync_series fetch-first ordering prevents them), so these are legacy rows from an older run. Delete the show and let the next scheduled sync rebuild it from scratch: delete from tvshow WHERE idShow = ; delete from tvshowlinkpath, genre_link, uniqueid, art, seasons, episode with the same idShow/files; then trigger a sync for that provider.

STV single-episode documentaries missing from library

Cause: STV returns episodes with episode_number=0 when playerSeries is null (no per-episode metadata). The _sync_series insert loop drops episode_number=0 via the if en_int < 1: continue guard, so documentaries and entire programmes without per-episode index info (Coronation Street, Emmerdale daily strips) would be missing from the library.

Fix: a renumber pre-pass in _sync_series at lines 1090–1112 groups episodes by season, finds the set of already-used episode numbers ≥1, and renumbers zero-numbered episodes to the next available slot within their season block. If season is also 0/missing, it's bumped to 1 so the show appears as Season 1 rather than the Kodi specials block (S00).

"Buried" C4 show appears as "Buried Hearts" — the same show fragmenting into two rows

Cause: TMDb's search-by-title re-ranks similar-named siblings dynamically. C4's Buried → TMDb can return Buried Hearts with a different tmdb_id on a different day. Each subsequent sync resolves the same title to a different canonical name and inserts episodes into the new row, fragmenting one show across multiple tvshow rows.

Fix (two layers): the TMDb disambiguation scorer (_pick_tmdb_tv_result) now ranks new-row candidates by title-similarity first (token Jaccard ×100), with year and overview as tie-breaks — so Buried (title similarity 1.0) beats Buried Hearts (0.29) when the query is "Buried". On subsequent syncs, _insert_tvshow looks up existing rows by the dir-name (prefixed_dirname) first, falling back to the TMDb canonical name. This keeps the local show identity stable even if TMDb's search re-ranks the title on a later pass.

Long-running C4 shows (Come Dine with Me, The Bill) lose their episodes

Cause: these daily strips produce __PARAMS__ JSON blocks over 600 KB. The c4_vod._extract_brand_data walker caps its scan at 4 MB; lines longer than the cap silently drop the brand data and fall through to "no episodes".

Fix: the cap sits at line 50 — raise it if you see a bigger show. The regex still bails at the first } that returns the brace depth to 0, so the cap is a safety bound, not the correctness boundary.

Playback

ITVX playback: 403 "Failed to authenticate HMAC" repeatedly

Cause: not actually an ITVX issue — this is the My5 symptom that's been mismarbled in your logs. If you're seeing it on My5 (Cassie) the cause is the C5 player JS has rotated the AES/HMAC keys, and the addon's cached key is the previous one.

Fix: my5._fetch_cassie already self-heals this — on a 403 with body "Failed to authenticate HMAC" it re-extracts keys from the live C5 player JS and retries once. If you're still seeing 403s after that, the path https://player.akamaized.net/html5player/core/html5-c5-player.js is no longer the right URL — C5 may have moved hosts. Check the network tab of the C5 web player to find the new JS bundle URL.

ITVX VOD: video plays but no audio on certain shows

Symptom: VOD content (especially non-ITV produced shows like Disney+ originals, "The Affair", "Downton Abbey Celebrates the Finale") plays video but audio is missing. The player's audio settings show "NONE". Affects all Kodi platforms — Pi, CoreELEC, Windows. The same content plays with audio in Chrome/Edge browsers.

Cause: The Irdeto license server assigns VMP entitlements (itvx_ctv_soft_protect_hd) per-content. On L3 Widevine (e.g. Raspberry Pi), VMP cannot be satisfied — the audio key oscillates between kUsable and kExpired/SystemCode5, so audio decryption never completes. This is NOT bypassable by changing platformTag — both "dotcom" and "ctv" receive the same entitlement. Video works because V4L2 hardware decode bypasses the CDM entirely; audio has no hardware path. Browsers satisfy VMP natively; Kodi's inputstream.adaptive cannot. See viwX #182 and Kodi forum #191, #202.

Current state: EasyPlayTV uses "platformTag": "dotcom" which limits VOD to 720p (no 1080p). Audio still fails on L3 — this is the same issue affecting viwX and all other L3 Widevine Kodi addons. Live channels are unaffected (already use "dotcom"). See IA PR #2021 and xbmc PR #28204 for the upstream fix implementing the CDM audio decoder interface that will bypass the single-decrypt VMP check (targeting Kodi v23, no ETA).

ITVX playback: "session expired - sign in again"

Cause: refresh token expired (they live ~30 days). The user's saved credentials in addon settings are still valid but the refresh-token grant needs a fresh login.

Fix: open the addon's settings → ITVX section → sign out, then sign in again. The addon calls itvx.login which uses the password grant directly (the cookie-based web flow isn't used because the API directly accepts password grant for the app.10ft.itv.com origin).

My5 premium content: 401 / 403 Bearer rejected on every playback

Cause: the saved Cognito session in addon_data/plugin.video.easyplaytv/my5_session has expired and the refresh token can no longer renew the access token (Cognito refresh tokens stay valid until revoked by GlobalSignOut, but server-side session invalidation can still revoke them — e.g. if you sign out via the My5 website).

Fix: open the addon's settings → Channel5 section → sign out, then sign in again. The addon calls my5.login which InitiateAuth(USER_PASSWORD_AUTH)'s against AWS Cognito directly and persists a fresh session dict (containing a new refresh_token) to my5_session. Note that free-to-air content will keep playing in the meantime — the _fetch_cassie retry logic drops the Authorization: Bearer header on 401/403 and re-issues the request anonymously.

My5 account challenge not supported: "SOFTWARE_TOKEN_MFA" / "NEW_PASSWORD_REQUIRED" / etc.

Cause: the Cognito InitiateAuth response came back with a ChallengeName instead of an AuthenticationResult. My5's hosted-UI web flow handles these (MFA, new-device, SRP, password-reset) but the addon's direct USER_PASSWORD_AUTH path does not.

Fix: sign in to channel5.com in a browser first and complete the challenge there. Once the account is in a state Cognito accepts for direct USER_PASSWORD_AUTH (typically: MFA disabled, password confirmed), the addon's ?action=my5_login will succeed and persist the session locally.

Sky News playback: "this content is not available in your region"

Cause: Brightcove's policy key rotation can ignore the X-Forwarded-For: 2.97.0.0 header sky.resolve sends. When the current Sky policy stops trusting the XFF header, the addon returns AU/US manifest URLs that don't play on a UK Kodi box.

Fix: if you're not on a UK IP, the addon has no remedy — Sky News only ships a UK stream. Run from a UK-IP egress (a VPN at the network layer) instead of relying on the XFF spoof. The XFF spoof is a per-policy workaround; assume it can break on any policy rotation.

Blaze shows empty catalogue

Cause: Blaze's HTML page scraper (blaze_vod.list_shows) regexes broke — Blaze changed class names or HTML structure on their static page.

Fix: open https://watch.blaze.tv/series in a browser, view source, grep for col-auto layout-carousel-column. If the class names changed, update the regex at blaze_vod.list_shows line 13 and the per-card regexes (lines 15-40). No JSON-API fallback exists.

OSMC / Pi-specific hardware

"EGL_BAD_SURFACE" with ITVX Widevine content on OSMC

Cause: inputstream.adaptive's secure-decoder path is broken on the Pi's V4L2 mem2mem hardware decoder — it tries to allocate secure surfaces that the Pi's V4L2 path can't honour, fails with EGL_BAD_SURFACE, and bails out of playback entirely.

Fix: set NOSECUREDECODER=true in inputstream.adaptive's settings on OSMC to force the V4L2 mem2mem hardware decoder instead of the broken secure decoder path for ITVX Widevine content. ITVX startup drops to ~5–8 s from click-to-play rather than the 30–60 s of EGL dithering.

~13 min startup delay after Kodi reboot

Cause: a stray malformed (unquoted XML) verboselog=true setting in the EasyPlayTV parent Series path row of MyVideos.path. Kodi's TMDb scraper logs 20K+ lines per /tv//season/N API call when the setting is on (pformat of the entire JSON response), costing ~22 s per season on RPi SD-card I/O — e.g. ~13 min for WWE Raw alone (35 seasons).

Fix: library_sync._sanitize_scraper_settings_xml quotes unquoted attributes and pins verboselog=false. If you see verbose log spam after a Kodi upgrade, manually update the strSettings column for the affected path row in the path table to set verboselog=false and re-quote any unquoted XML attributes.

Kodi crashes 3× in 5 minutes after reboot on Pi 4 / Pi 3 ("mmap of bo N failed", "[drm] Resetting GPU")

Cause: GPU/CMA memory exhaustion. Kodi's library scanner fires ffmpeg probes for every entry in the video DB on boot — with myvideos.extractflags and myvideos.extractchapterthumbs set to true (Kodi's defaults), each probe allocates a V4L2 decoder context + scratch frames. With a few hundred large .mkv files this exhausts the 256 MiB CMA pool on the Pi in a few seconds. The kernel driver fails the mmap, the GPU is reset, and Kodi's mediacenter service restarts — only to repeat the cycle on the next boot's scan.

Symptoms: journalctl -u mediacenter shows repeated mmap of bo N (offset …, size …) failed entries; dmesg shows [drm] Resetting GPU.; kodi.log is filled with LoadFile: Failed to load ….mkv: out of memory lines.

Fix: turn off the ffmpeg-probe settings in guisettings.xml:

false
false

…then restart mediacenter.service. The EasyPlayTV sync already writes its own poster/art rows directly via SQL, so Kodi's ffmpeg-probe is not needed for the addon's library entries. Only the disk-based .mkv library (for non-addon content you also host locally) loses auto-generated thumbnails — a small price to pay for a stable boot.

Manual syncs / external triggers

Manual / forced sync removed

Earlier releases supported forcing a sync via a marker file (force_sync_<provider> in the video addon's profile), an HTTP POST /sync/vod/<provider> endpoint, and a --sync CLI flag. These were all removed — the only sync path is now the scheduled sequential batch (providers one-after-another, then PVR refresh), capped by the sync interval (VOD sync hours / vod_sync.interval_hours). To sync more often, lower that interval (1 = hourly).