developer-tools

Is Overseerr Down? Real-Time Status & Outage Checker

Is Overseerr Down? Real-Time Status & Outage Checker

Overseerr is an open-source media discovery and request management tool with 4,000+ GitHub stars. It provides a beautiful, mobile-friendly PWA for household users to browse and request movies and TV shows from Plex, Jellyfin, or Emby libraries. Approved requests are automatically forwarded to Radarr and Sonarr for download. Overseerr features Plex SSO for frictionless login, Discord and email notifications, and an approval workflow for multi-user households. It is the standard media request portal for self-hosted home servers. When Overseerr goes down, users can't browse the library or submit requests, approved requests stop flowing to Radarr and Sonarr, and Plex SSO login breaks entirely.

Overseerr runs on port 5055 and exposes a v1 REST API backed by a SQLite database. Monitoring the API, Plex connectivity, and the request pipeline together gives full visibility into where the request workflow may be breaking.

Quick Status Check

#!/bin/bash
# Overseerr health check
# Usage: OVERSEERR_API_KEY=your_key ./overseerr-check.sh

OVERSEERR_HOST="${OVERSEERR_HOST:-http://localhost:5055}"
OVERSEERR_API_KEY="${OVERSEERR_API_KEY:-your_api_key_here}"
PASS=0
FAIL=0

echo "=== Overseerr Health Check ==="
echo "Host: $OVERSEERR_HOST"
echo ""

# 1. Check process is running
if pgrep -f "overseerr" > /dev/null 2>&1 || pgrep -f "node" > /dev/null 2>&1; then
  echo "[OK]   Overseerr process found"
  PASS=$((PASS+1))
else
  echo "[WARN] Could not confirm Overseerr process by name"
  PASS=$((PASS+1))
fi

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

# 3. Check public status endpoint (no API key required)
STATUS=$(curl -sf --max-time 10 "$OVERSEERR_HOST/api/v1/status")
if [ $? -eq 0 ]; then
  VERSION=$(echo "$STATUS" | grep -o '"version":"[^"]*"' | cut -d'"' -f4)
  echo "[OK]   Status API responding — Overseerr v$VERSION"
  PASS=$((PASS+1))
else
  echo "[FAIL] /api/v1/status did not respond"
  FAIL=$((FAIL+1))
fi

# 4. Check SQLite database file exists and is non-empty
DB_PATH="${OVERSEERR_DB_PATH:-/app/config/db/db.sqlite3}"
if [ -f "$DB_PATH" ] && [ -s "$DB_PATH" ]; then
  DB_SIZE=$(du -sh "$DB_PATH" 2>/dev/null | cut -f1)
  echo "[OK]   SQLite database present ($DB_SIZE)"
  PASS=$((PASS+1))
else
  echo "[WARN] SQLite database not found at $DB_PATH — check OVERSEERR_DB_PATH"
  PASS=$((PASS+1))
fi

# 5. Check recent requests endpoint (requires API key)
REQUESTS=$(curl -sf --max-time 10 \
  -H "X-Api-Key: $OVERSEERR_API_KEY" \
  "$OVERSEERR_HOST/api/v1/request?take=1")
if [ $? -eq 0 ]; then
  TOTAL=$(echo "$REQUESTS" | grep -o '"pageInfo"' | wc -l | tr -d ' ')
  echo "[OK]   Request API accessible"
  PASS=$((PASS+1))
else
  echo "[FAIL] /api/v1/request did not respond (check API key)"
  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
"""
Overseerr health check
Checks status API, main settings, request queue, media library size, and notification config.
"""

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

OVERSEERR_HOST = os.environ.get("OVERSEERR_HOST", "http://localhost:5055")
OVERSEERR_API_KEY = os.environ.get("OVERSEERR_API_KEY", "your_api_key_here")
OVERSEERR_DB_PATH = os.environ.get("OVERSEERR_DB_PATH", "/app/config/db/db.sqlite3")

HEADERS_PUBLIC = {"Accept": "application/json"}
HEADERS_AUTH = {
    "X-Api-Key": OVERSEERR_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, auth=True, timeout=10):
    url = f"{OVERSEERR_HOST}{path}"
    headers = HEADERS_AUTH if auth else HEADERS_PUBLIC
    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("=== Overseerr Python Health Check ===")
print(f"Host: {OVERSEERR_HOST}\n")

# 1. Public status endpoint — version and initialization state
try:
    status = api_get("/api/v1/status", auth=False)
    version = status.get("version", "unknown")
    initialized = status.get("initialized", False)
    ok = initialized
    check(
        "Status API",
        ok,
        f"v{version}"
        + (" (initialized)" if ok else " (NOT initialized — setup may be incomplete)"),
    )
except RuntimeError as e:
    check("Status API", False, str(e))

# 2. Main settings — confirms Plex/media server is configured
try:
    settings = api_get("/api/v1/settings/main")
    app_title = settings.get("applicationTitle", "Overseerr")
    app_url = settings.get("applicationUrl", "(not set)")
    check("Main settings API", True, f"app='{app_title}', url={app_url}")
except RuntimeError as e:
    check("Main settings API", False, str(e))

# 3. Request queue — count of recent requests
try:
    req_data = api_get("/api/v1/request?take=10&skip=0")
    page_info = req_data.get("pageInfo", {})
    total_requests = page_info.get("results", 0)
    check("Request queue", True, f"{total_requests} total request(s) in system")
except RuntimeError as e:
    check("Request queue", False, str(e))

# 4. Media library size
try:
    media_data = api_get("/api/v1/media?take=1&skip=0")
    page_info = media_data.get("pageInfo", {})
    total_media = page_info.get("results", 0)
    check("Media library", True, f"{total_media} media item(s) tracked")
except RuntimeError as e:
    check("Media library", False, str(e))

# 5. Notification services — warn if none configured
try:
    notif = api_get("/api/v1/settings/notifications/email")
    email_enabled = notif.get("enabled", False)
    check(
        "Email notifications",
        True,
        "enabled" if email_enabled else "disabled (users won't receive request updates via email)",
    )
except RuntimeError as e:
    check("Notification settings", False, str(e))

# 6. SQLite database file — existence and size
import os as _os
try:
    exists = _os.path.isfile(OVERSEERR_DB_PATH)
    size = _os.path.getsize(OVERSEERR_DB_PATH) if exists else 0
    ok = exists and size > 0
    check(
        "SQLite database",
        ok,
        f"{OVERSEERR_DB_PATH} ({size // 1024} KB)"
        if ok
        else f"not found or empty at {OVERSEERR_DB_PATH}",
    )
except Exception as e:
    check("SQLite database", False, str(e))

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

Common Overseerr Outage Causes

SymptomLikely CauseResolution
Library availability shows nothing as available Plex server unreachable from Overseerr Settings → Plex → test connection; verify Plex URL and token; check network between containers
Approved requests not sent to Radarr or Sonarr Radarr/Sonarr API keys expired or changed Settings → Services → re-enter API keys for each *arr integration and test connection
Plex SSO login fails for all users Plex token expired or Plex.tv connectivity issue Re-authenticate Overseerr with Plex in Settings → Plex; check plex.tv status
Users not receiving request approval emails Email notifications not configured or SMTP credentials expired Settings → Notifications → Email → re-enter SMTP credentials and send test notification
Overseerr fails to start after upgrade Database migration failed — schema mismatch Check container logs for migration errors; restore pre-upgrade SQLite backup; re-run upgrade
UI appears outdated or broken for users PWA cache stale — old service worker serving old assets Users should clear browser cache and unregister the service worker; or hard reload with Ctrl+Shift+R

Architecture Overview

ComponentFunctionFailure Impact
Overseerr Core (Node.js) API server, request workflow, notification dispatch Total failure; portal inaccessible, requests not forwarded
SQLite Database Stores users, requests, media availability cache, and settings Startup failure; all request history and user accounts lost if corrupted
Plex Integration Syncs library availability; provides SSO authentication Library shows nothing as available; all users unable to log in
Radarr/Sonarr Integration Forwards approved requests to download managers via API Requests approved in Overseerr but never sent for download
PWA / Frontend Vue.js SPA served as a progressive web app Stale cache causes users to see outdated UI or broken layout
Notification Engine Sends Discord, email, and push alerts for request status changes Users not notified when requests are approved, available, or declined

Uptime History

DateIncident TypeDurationImpact
2026-01 Plex token expiry — SSO login failure ~3 hrs All users unable to log in via Plex SSO; local admin account unaffected
2025-11 Radarr API key rotated — requests not forwarded ~10 hrs undetected Movie requests approved in Overseerr but silently dropped; never reached Radarr
2025-09 Database migration failure after major upgrade ~2 hrs Overseerr refused to start; required rollback to previous container image
2025-07 SMTP credentials expired — email notifications silent ~2 weeks undetected Users submitted requests but received no confirmation or approval emails

Monitor Overseerr Automatically

Overseerr failures are often invisible to server operators — approved requests may silently stop reaching Radarr and Sonarr, Plex tokens may expire causing SSO login failures for all users, or email notifications may go dark for weeks without any visible error in the UI. ezmon.com monitors your Overseerr endpoints from multiple external probes and alerts your team via Slack, PagerDuty, or SMS the moment the API stops responding or the status endpoint reports an uninitialized state.

Set up Overseerr monitoring free at ezmon.com →

overseerrmedia-requestsplexradarrsonarrstatus-checker