Malware disguised as MKV files on public trackers
My TV import rate had collapsed from about 90 episodes a day to single digits over a five-day stretch. Sonarr's queue was full but nothing was making it into Emby. Time to figure out why my pipeline had gone silent.
What was happening
Sonarr's queue showed 374 items. About 200 of them were marked importBlocked with a warning: "executable file." The rest were a mix of stalled downloads and "Episode file already imported" messages for shows I knew hadn't actually been imported.
I pulled a sample of the blocked filenames. Every one of them came from one of three release group tags: -ETHEL, -EDITH, or -DOLORES. They were attached to nearly every popular current show — the kind of releases that get the most grabs.
What I found
The files were .mkv containers wrapping a payload .exe or .scr. Some had a tiny throwaway video stream so they'd pass a quick eyeball check; others were just the executable with a .mkv extension. Sonarr's import validator correctly refused all of them — it checks for forbidden extensions inside the candidate file, and won't move anything containing .exe, .scr, .lnk, .bat, .cmd, .js, or .vbs.
The problem wasn't that Sonarr was importing junk. It was that Sonarr would block the bad release, sit on it in the queue, and not automatically search again. Each malware-tagged release was sticky-blocking the slot that should have rotated through to a legitimate one. Meanwhile, qBittorrent kept the corresponding .mkv file (the payload) on disk because the torrent technically completed.
The 203 "already imported" entries were a separate but related issue: phantom queue items for old kids' shows that had been imported months ago, getting re-grabbed because Sonarr's Episode file already imported failure doesn't always get blocklisted.
The fix
Three steps. First, mass-clear the polluted queue:
# get all importBlocked + stalled queue ids
curl -s "$SONARR/api/v3/queue?pageSize=500" \
| jq -r '.records[] | select(.trackedDownloadState=="importBlocked" or
.status=="warning") | .id' \
| xargs -I{} curl -X DELETE \
"$SONARR/api/v3/queue/{}?removeFromClient=true&blocklist=true"
Second, a release profile that refuses to grab these in the first place:
Name: Block malware-attaching scene fakes
Ignored: -ETHEL, -EDITH, -DOLORES
Ignored regex: /\.(exe|scr|lnk|bat|cmd|js|vbs)\b/i
Third, kick a missing-episode search to repopulate with clean releases:
curl -X POST "$SONARR/api/v3/command" \
-H "X-Api-Key: $KEY" \
-d '{"name":"MissingEpisodeSearch"}'
What I'd do differently
The release profile lives in Sonarr now, but the more general lesson is to treat the indexer feed as untrusted input. Any time grab volume drops dramatically week-over-week, the first thing to look at is the ratio of importBlocked to total queue depth. If a single release group shows up as the source of most blocks, blocklist it before the queue clogs. I have a Sunday morning cron job now that surfaces release groups with more than five blocked imports in the past 24 hours.