developer-tools

Is Radarr Down? Real-Time Status & Outage Checker

Is Radarr Down? Real-Time Status & Outage Checker

Radarr is an open-source movie collection manager and download automation tool with 10,000+ GitHub stars. A fork of Sonarr adapted for movies, Radarr monitors for new movie releases, grabs them from Usenet and BitTorrent indexers, and imports them to your library with proper naming conventions. It integrates with Plex, Jellyfin, Emby, and all major download clients — making it the *arr suite standard for automated movie management. Home media server operators rely on Radarr running continuously to keep their libraries current; when it goes down, new releases are missed, queued downloads stall, and import pipelines break silently.

Radarr exposes a full REST API on port 7878. Monitoring both the process and the API health endpoint — combined with disk space and download queue checks — is essential to catching failures before your movie library falls behind.

Quick Status Check

#!/bin/bash
# Radarr health check
# Usage: RADARR_API_KEY=your_key ./radarr-check.sh

RADARR_HOST="${RADARR_HOST:-http://localhost:7878}"
RADARR_API_KEY="${RADARR_API_KEY:-your_api_key_here}"
PASS=0
FAIL=0

echo "=== Radarr Health Check ==="
echo "Host: $RADARR_HOST"
echo ""

# 1. Check process is running
if pgrep -x "Radarr" > /dev/null 2>&1 || pgrep -f "Radarr.exe" > /dev/null 2>&1; then
  echo "[OK]   Radarr process is running"
  PASS=$((PASS+1))
else
  echo "[FAIL] Radarr process not found"
  FAIL=$((FAIL+1))
fi

# 2. Check port 7878 is open
if nc -z localhost 7878 2>/dev/null; then
  echo "[OK]   Port 7878 is open"
  PASS=$((PASS+1))
else
  echo "[FAIL] Port 7878 is not reachable"
  FAIL=$((FAIL+1))
fi

# 3. Check system status API
STATUS=$(curl -sf --max-time 10 \
  -H "X-Api-Key: $RADARR_API_KEY" \
  "$RADARR_HOST/api/v3/system/status")
if [ $? -eq 0 ]; then
  VERSION=$(echo "$STATUS" | grep -o '"version":"[^"]*"' | cut -d'"' -f4)
  echo "[OK]   API responding — Radarr v$VERSION"
  PASS=$((PASS+1))
else
  echo "[FAIL] /api/v3/system/status did not respond"
  FAIL=$((FAIL+1))
fi

# 4. Check health endpoint for issues
HEALTH=$(curl -sf --max-time 10 \
  -H "X-Api-Key: $RADARR_API_KEY" \
  "$RADARR_HOST/api/v3/health")
if [ $? -eq 0 ]; then
  ISSUE_COUNT=$(echo "$HEALTH" | grep -o '"type":"' | wc -l | tr -d ' ')
  if [ "$ISSUE_COUNT" -eq 0 ]; then
    echo "[OK]   Health check clean — no issues reported"
  else
    echo "[WARN] Health check returned $ISSUE_COUNT issue(s):"
    echo "$HEALTH" | grep -o '"message":"[^"]*"' | cut -d'"' -f4 | while read -r msg; do
      echo "       - $msg"
    done
  fi
  PASS=$((PASS+1))
else
  echo "[FAIL] /api/v3/health did not respond"
  FAIL=$((FAIL+1))
fi

echo ""
echo "=== Result: $PASS passed, $FAIL failed ==="
[ "$FAIL" -eq 0 ] && exit 0 || exit 1

Python Health Check

#!/usr/bin/env python3
"""
Radarr health check
Checks system status, health issues, download queue, missing movies, library size, and disk space.
"""

import os
import sys
import json
import urllib.request
import urllib.error

RADARR_HOST = os.environ.get("RADARR_HOST", "http://localhost:7878")
RADARR_API_KEY = os.environ.get("RADARR_API_KEY", "your_api_key_here")

HEADERS = {
    "X-Api-Key": RADARR_API_KEY,
    "Accept": "application/json",
}

results = []
failures = 0


def check(label, ok, detail=""):
    global failures
    status = "OK  " if ok else "FAIL"
    if not ok:
        failures += 1
    msg = f"[{status}] {label}"
    if detail:
        msg += f" — {detail}"
    results.append(msg)
    print(msg)


def api_get(path, timeout=10):
    url = f"{RADARR_HOST}{path}"
    req = urllib.request.Request(url, headers=HEADERS)
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        raise RuntimeError(f"HTTP {e.code} from {path}")
    except Exception as e:
        raise RuntimeError(f"Request failed: {e}")


print("=== Radarr Python Health Check ===")
print(f"Host: {RADARR_HOST}\n")

# 1. System status — version and OS
try:
    status = api_get("/api/v3/system/status")
    version = status.get("version", "unknown")
    branch = status.get("branch", "unknown")
    os_name = status.get("osName", "unknown")
    check("System status API", True, f"v{version} ({branch}) on {os_name}")
except RuntimeError as e:
    check("System status API", False, str(e))

# 2. Health endpoint — list WARNING or ERROR items
try:
    health = api_get("/api/v3/health")
    issues = [h for h in health if h.get("type") in ("warning", "error")]
    if not issues:
        check("Health endpoint", True, "no issues reported")
    else:
        check("Health endpoint", False, f"{len(issues)} issue(s) found")
        for issue in issues:
            print(f"       [{issue.get('type','?').upper()}] {issue.get('message','')}")
except RuntimeError as e:
    check("Health endpoint", False, str(e))

# 3. Download queue — count of active items
try:
    queue = api_get("/api/v3/queue")
    total = queue.get("totalRecords", 0)
    check("Download queue", True, f"{total} item(s) in queue")
except RuntimeError as e:
    check("Download queue", False, str(e))

# 4. Wanted/missing — movies Radarr hasn't been able to grab
try:
    missing = api_get("/api/v3/wanted/missing?pageSize=1")
    total_missing = missing.get("totalRecords", 0)
    ok = total_missing < 200
    check(
        "Wanted/missing movies",
        ok,
        f"{total_missing} missing movie(s)"
        + ("" if ok else " — unusually high, check indexers"),
    )
except RuntimeError as e:
    check("Wanted/missing movies", False, str(e))

# 5. Movie library count
try:
    movies = api_get("/api/v3/movie")
    count = len(movies) if isinstance(movies, list) else 0
    check("Movie library", True, f"{count} movies tracked")
except RuntimeError as e:
    check("Movie library", False, str(e))

# 6. Disk space — warn if any path has less than 10 GB free
try:
    disks = api_get("/api/v3/diskspace")
    low = [
        d for d in disks
        if d.get("freeSpace", 999999999999) < 10 * 1024 ** 3
    ]
    if not low:
        check("Disk space", True, f"{len(disks)} path(s) checked, all above 10 GB free")
    else:
        for d in low:
            free_gb = d.get("freeSpace", 0) / 1024 ** 3
            check("Disk space", False, f"{d.get('path','?')} has only {free_gb:.1f} GB free")
except RuntimeError as e:
    check("Disk space", False, str(e))

# Summary
print(f"\n=== Result: {len(results) - failures} passed, {failures} failed ===")
sys.exit(0 if failures == 0 else 1)

Common Radarr Outage Causes

SymptomLikely CauseResolution
Movies queue up but never download Download client disconnected or credentials changed Settings → Download Clients → test connection; update API key or password
Indexer searches return no results Indexer blacklisted after repeated failures Settings → Indexers → check for blacklist warning; re-enable or replace indexer
Movie metadata fails to load or is missing TMDb API connectivity issue or rate limit exceeded Check Radarr logs for TMDb errors; wait for rate limit reset or verify network access to api.themoviedb.org
Completed downloads not imported into library Disk full on target media drive Run df -h on media path; free space or adjust storage; check Radarr diskspace API
Download present on disk but not in library Import failure — wrong filename format or permissions error Check Activity → Queue for import errors; verify Radarr has write access to media folder
Same movie downloaded repeatedly Upgrade loop — quality cutoff never satisfied by available releases Settings → Profiles → raise quality cutoff or mark movie as "don't upgrade"

Architecture Overview

ComponentFunctionFailure Impact
Radarr Core (C#/.NET) Main process — scheduling, API, import logic Total failure; all grabs and imports stop
SQLite Database Stores movie list, history, quality profiles, and indexer config Crash on startup; full library config lost if corrupted
Indexer RSS/Newznab/Torznab Engine Searches indexers for movie releases matching quality profiles No new grabs; existing downloads unaffected
Download Client Integration Sends NZB/torrent to configured download client Movies found but never dispatched to downloader
Import/Rename Engine Moves completed downloads into library with TMDb-sourced naming Downloads complete but library not updated
Media Server Notification Triggers Plex/Jellyfin/Emby refresh after successful import Files present on disk but invisible in media server UI

Uptime History

DateIncident TypeDurationImpact
2026-02 Upgrade loop on popular release ~8 hrs of repeated downloads Same movie downloaded 6 times; disk space consumed until manually resolved
2025-11 TMDb API outage ~4 hrs New movie adds failed; existing library unaffected
2025-09 Disk full — import path exhausted ~6 hrs undetected Completed downloads accumulated in temp folder; imports silently failed
2025-07 SQLite corruption after forced shutdown ~2 hrs (restore from backup) Radarr offline; full movie list and history required restore

Monitor Radarr Automatically

Radarr failures are frequently invisible — the web UI may appear healthy while the download client connection is silently broken, disk space is exhausted, or an indexer blacklist is blocking all searches. ezmon.com monitors your Radarr endpoints from multiple external probes and alerts your team via Slack, PagerDuty, or SMS the moment the API stops responding or the health endpoint surfaces critical errors.

Set up Radarr monitoring free at ezmon.com →

radarrmedia-managementhome-serverself-hostedmovie-downloadsstatus-checker