ArrStalledHandler
ArrStalledHandler is a Python script to manage stalled downloads in Radarr and Sonarr. It identifies stalled downloads, tracks them in a database, and performs configurable actions such as removing, blocklisting, or re-searching. Easily deployable via Docker with customizable settings for seamless automation.
Install / Use
/learn @tommyvange/ArrStalledHandlerREADME
ArrStalledHandler
ArrStalledHandler is a Python-based script designed to handle stalled downloads in Radarr, Sonarr, Lidarr and Readarr by taking actions such as removing, blocklisting, or blocklisting and re-searching for the affected items. It supports configuration through a .env file, logging for visibility, and is deployable via Docker for ease of use.
This repository is licensed under the GNU General Public License v3.0 (GPLv3).
Created by Tommy Vange Rød. You can see the full list of credits here.
This project is available on GitHub, Docker Hub and the Unraid Community App store.
Features
- Automatic Handling of Stalled Downloads:
- Detect stalled downloads based on error messages from Radarr/Sonarr/Lidarr/Readarr queues.
- Detect download stuck on "Downloading Metadata" in qBittorrent and treat them as stalled.
- Perform configurable actions such as:
- Remove the stalled download.
- Blocklist the stalled download.
- Blocklist and re-trigger a search for the movie or episodes.
- Database Tracking:
- Tracks stalled downloads in a SQLite database to ensure actions are only taken after a specified timeout period.
- Logging:
- Verbose and informative logging controlled via configuration.
- Docker Support:
- Easily deployable with Docker and customizable run intervals.
Configuration
The script is fully configurable using environment variables specified in a .env file. Below is a description of each configuration option:
.env Variables
| Variable | Description | Default Value |
|-----------------------------------------|-------------------------------------------------------------------------------------------------|------------------------|
| RADARR_URL | The base URL for Radarr's API. Example: http://localhost:7878,http://otherhost:7878. | None (required) |
| RADARR_API_KEY | The API key for Radarr (found in Radarr settings). | None (required) |
| SONARR_URL | The base URL for Sonarr's API. Example: http://localhost:8989,http://otherhost:8989. | None (required) |
| SONARR_API_KEY | The API key for Sonarr (found in Sonarr settings). | None (required) |
| LIDARR_URL | The base URL for Lidarr's API. Example: http://localhost:8686,http://otherhost:8686. | None (required) |
| LIDARR_API_KEY | The API key for Lidarr (found in Radarr settings). | None (required) |
| READARR_URL | The base URL for Readarr's API. Example: http://localhost:8787,http://otherhost:8787. | None (required) |
| READARR_API_KEY | The API key for Readarr (found in Sonarr settings). | None (required) |
| STALLED_TIMEOUT | Time (in seconds) a download must remain stalled before actions are taken. | 3600 (1 hour) |
| STALLED_ACTION | Action to perform on stalled downloads: REMOVE, BLOCKLIST, or BLOCKLIST_AND_SEARCH. | BLOCKLIST_AND_SEARCH |
| VERBOSE | Enable verbose logging for debugging (true or false). | false |
| RUN_INTERVAL | Time (in seconds) between script executions when running in Docker. | 300 (5 minutes) |
| COUNT_DOWNLOADING_METADATA_AS_STALLED | Weather the script should count downloads with the status of "Downloading Metadata" as stalled. | false |
To disable Radarr or Sonarr; leave the URL empty in the environment. If the service does not have a URL, then it is skipped. Multple services are allowed by using comma seperated values.
How It Works
Script Workflow
-
Initialization:
- The script initializes a SQLite database (
stalled_downloads.db) to track stalled downloads. - It fetches the current queue from Radarr and Sonarr APIs.
- The script initializes a SQLite database (
-
Detect Stalled Downloads:
- The script identifies stalled downloads based on the error message:
"The download is stalled with no connections". - [Optional] The script treats downloads with the error message
"qBittorrent is downloading metadata"as stalled.
- The script identifies stalled downloads based on the error message:
-
Timeout Check:
- Downloads are only handled if they have been stalled longer than the configured
STALLED_TIMEOUT.
- Downloads are only handled if they have been stalled longer than the configured
-
Perform Configured Action:
- Based on the
STALLED_ACTIONsetting:- REMOVE: Removes the stalled download.
- BLOCKLIST: Removes and blocklists the stalled download.
- BLOCKLIST_AND_SEARCH: Removes, blocklists, and re-triggers a search for the movie or episodes.
- Based on the
-
Logging:
- Logs detailed information about each action for visibility.
-
Repeat:
- When running in Docker, the script waits for the
RUN_INTERVALduration and repeats the process.
- When running in Docker, the script waits for the
Deployment
Unraid Deployment

- Install the Community Apps extension as documented in this guide.
- Go to the Apps-section in your Unraid web-ui.
- Search for ArrStalledHandler.
- Click Install on the application.
- Fill out the variables according to the Configuration.
- Click Apply.
Now the container should automatically start up and start handling your stalled downloads.
Docker Deployment (Docker Hub)
Docker compose
More info at Docker Docs.
services:
arr-stalled-handler:
image: tommythebeast/arrstalledhandler:latest
container_name: ArrStalledHandler
restart: unless-stopped
environment:
RADARR_URL: "http://localhost:7878,http://otherhost:7878"
RADARR_API_KEY: "your_radarr_api_key,your_2nd_radarr_api_key"
SONARR_URL: "http://localhost:8989,http://otherhost:8989"
SONARR_API_KEY: "your_sonarr_api_key,your_2nd_sonarr_api_key"
LIDARR_URL: "http://localhost:8686,http://otherhost:8686"
LIDARR_API_KEY: "your_lidarr_api_key,your_2nd_lidarr_api_key"
READARR_URL: "http://localhost:8787,http://otherhost:8787"
READARR_API_KEY: "your_readarr_api_key,our_2nd_readarr_api_key"
STALLED_TIMEOUT: "3600"
STALLED_ACTION: "BLOCKLIST_AND_SEARCH"
VERBOSE: "false"
RUN_INTERVAL: "300"
COUNT_DOWNLOADING_METADATA_AS_STALLED: "false"
Docker CLI
More info at Docker Docs.
Multi-line:
docker run -d \
--name=ArrStalledHandler \
-e RADARR_URL=http://localhost:7878,http://otherhost:7878 \
-e RADARR_API_KEY=your_radarr_api_key,your_2nd_radarr_api_key \
-e SONARR_URL=http://localhost:8989,http://otherhost:8989 \
-e SONARR_API_KEY=your_sonarr_api_key,your_2nd_sonarr_api_key \
-e LIDARR_URL=http://localhost:8686,http://otherhost:8686 \
-e LIDARR_API_KEY=your_lidarr_api_key,your_2nd_lidarr_api_key \
-e READARR_URL=http://localhost:8787,http://otherhost:8787 \
-e READARR_API_KEY=your_readarr_api_key,our_2nd_readarr_api_key \
-e STALLED_TIMEOUT=3600 \
-e STALLED_ACTION=BLOCKLIST_AND_SEARCH \
-e VERBOSE=false \
-e RUN_INTERVAL=300 \
-e COUNT_DOWNLOADING_METADATA_AS_STALLED=false \
--restart unless-stopped \
tommythebeast/arrstalledhandler:latest
One line:
docker run -d --name=ArrStalledHandler -e RADARR_URL=http://localhost:7878,http://otherhost:7878 -e RADARR_API_KEY=your_radarr_api_key,your_2nd_radarr_api_key -e SONARR_URL=http://localhost:8989,http://otherhost:8989 -e SONARR_API_KEY=your_sonarr_api_key,your_2nd_sonarr_api_key -e LIDARR_URL=http://localhost:8686,http://otherhost:8686 -e LIDARR_API_KEY=your_lidarr_api_key,your_2nd_lidarr_api_key -e READARR_URL=http://localhost:8787,http://otherhost:8787 -e READARR_API_KEY=your_readarr_api_key,our_2nd_readarr_api_key -e STALLED_TIMEOUT=3600 -e STALLED_ACTION=BLOCKLIST_AND_SEARCH -e VERBOSE=false -e RUN_INTERVAL=300 -e COUNT_DOWNLOADING_METADATA_AS_STALLED=false --restart unless-stopped tommythebeast/arrstalledhandler:latest
Docker Deployment (Manual)
-
Clone the Repository:
git clone https://github.com/your-username/ArrStalledHandler.git cd ArrStalledHandler -
Configure Environment:
Create a
.envfile and populate it with the required variables:RADARR_URL=http://local
