developer-tools

Is Bazarr Down? Real-Time Status & Outage Checker

Is Bazarr Down? Real-Time Status & Outage Checker

Bazarr is an open-source subtitle management application with 3,000+ GitHub stars, built as a companion app to Sonarr and Radarr. It automatically downloads and manages subtitles for movies and TV shows, supporting 100+ subtitle providers (OpenSubtitles, Subscene, Addic7ed, and more) and 40+ languages. Bazarr integrates seamlessly with the *arr suite and media servers including Plex, Jellyfin, and Emby, making it the standard solution for automated subtitle acquisition in home media servers. When Bazarr goes down, subtitle downloads stop, and viewers relying on subtitles for foreign-language or accessibility purposes are left without them as new content arrives.

Bazarr exposes a REST API on port 6767. Monitoring the process, the API health endpoint, and provider connectivity is the fastest way to catch failures before your library accumulates a backlog of content missing subtitles.

Quick Status Check

#!/bin/bash
# Bazarr health check
# Usage: BAZARR_API_KEY=your_key ./bazarr-check.sh

BAZARR_HOST="${BAZARR_HOST:-http://localhost:6767}"
BAZARR_API_KEY="${BAZARR_API_KEY:-your_api_key_here}"
PASS=0
FAIL=0

echo "=== Bazarr Health Check ==="
echo "Host: $BAZARR_HOST"
echo ""

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

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

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

# 4. Check health endpoint
HEALTH=$(curl -sf --max-time 10 \
  -H "X-API-KEY: $BAZARR_API_KEY" \
  "$BAZARR_HOST/api/system/health")
if [ $? -eq 0 ]; then
  ISSUE_COUNT=$(echo "$HEALTH" | grep -o '"issue"' | 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)"
  fi
  PASS=$((PASS+1))
else
  echo "[FAIL] /api/system/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
"""
Bazarr health check
Checks system status, health issues, active subtitle providers, missing subtitles for
episodes and movies, and Sonarr/Radarr connectivity.
"""

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

BAZARR_HOST = os.environ.get("BAZARR_HOST", "http://localhost:6767")
BAZARR_API_KEY = os.environ.get("BAZARR_API_KEY", "your_api_key_here")

HEADERS = {
    "X-API-KEY": BAZARR_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"{BAZARR_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("=== Bazarr Python Health Check ===")
print(f"Host: {BAZARR_HOST}\n")

# 1. System status — version and uptime
try:
    status = api_get("/api/system/status")
    version = status.get("bazarr_version", "unknown")
    python_version = status.get("python_version", "unknown")
    check("System status API", True, f"v{version} (Python {python_version})")
except RuntimeError as e:
    check("System status API", False, str(e))

# 2. Health endpoint — list any reported issues
try:
    health = api_get("/api/system/health")
    issues = health if isinstance(health, list) else health.get("data", [])
    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] {issue.get('issue', issue)}")
except RuntimeError as e:
    check("Health endpoint", False, str(e))

# 3. Subtitle providers — warn if none are enabled
try:
    providers = api_get("/api/providers")
    provider_list = providers if isinstance(providers, list) else providers.get("data", [])
    enabled = [p for p in provider_list if p.get("enabled", False)]
    ok = len(enabled) > 0
    check(
        "Subtitle providers",
        ok,
        f"{len(enabled)} of {len(provider_list)} provider(s) enabled"
        + ("" if ok else " — all providers disabled, no subtitles will download"),
    )
except RuntimeError as e:
    check("Subtitle providers", False, str(e))

# 4. Episodes missing subtitles
try:
    wanted_eps = api_get("/api/episodes/wanted?start=0&length=1")
    total_ep = wanted_eps.get("total", 0)
    ok = total_ep < 500
    check(
        "Episodes missing subtitles",
        ok,
        f"{total_ep} episode(s) missing subtitles"
        + ("" if ok else " — unusually high, check provider status"),
    )
except RuntimeError as e:
    check("Episodes missing subtitles", False, str(e))

# 5. Movies missing subtitles
try:
    wanted_movies = api_get("/api/movies/wanted?start=0&length=1")
    total_mv = wanted_movies.get("total", 0)
    ok = total_mv < 200
    check(
        "Movies missing subtitles",
        ok,
        f"{total_mv} movie(s) missing subtitles"
        + ("" if ok else " — unusually high, check provider status"),
    )
except RuntimeError as e:
    check("Movies missing subtitles", False, str(e))

# 6. Sonarr connectivity — confirms *arr integration is live
try:
    sonarr = api_get("/api/sonarr/series?start=0&length=1")
    total = sonarr.get("total", -1)
    ok = total >= 0
    check(
        "Sonarr connectivity",
        ok,
        f"{total} series synced from Sonarr" if ok else "Sonarr connection failed",
    )
except RuntimeError as e:
    check("Sonarr connectivity", False, str(e))

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

Common Bazarr Outage Causes

SymptomLikely CauseResolution
No subtitles downloading for any content All subtitle providers rate limited or API keys expired Settings → Providers → test each provider; renew OpenSubtitles credentials; check provider status pages
Bazarr not syncing new episodes or movies Sonarr or Radarr connection broken after credential change Settings → Sonarr/Radarr → test connection; re-enter API key if recently rotated
Bazarr web UI not loading Python Flask app crashed or failed to start Check Bazarr logs; restart the Bazarr service; verify Python dependencies with pip check
Bazarr crashes on startup SQLite database corruption after unclean shutdown Stop Bazarr; run sqlite3 bazarr.db "PRAGMA integrity_check"; restore from backup
Subtitles download but audio sync is wrong ffsubsync audio-based sync broken or ffmpeg not installed Verify ffmpeg is installed and on PATH; test ffsubsync manually; disable auto-sync as a workaround
OpenSubtitles returns no results Provider credentials expired — OpenSubtitles login fails Settings → Providers → OpenSubtitles → re-enter username and password; verify account is not banned

Architecture Overview

ComponentFunctionFailure Impact
Bazarr Core (Python/Flask) Main process — web UI, API, scheduler, subtitle logic Total failure; all subtitle downloads and syncs stop
SQLite Database Stores media library sync, subtitle history, and settings Crash on startup; subtitle history and provider config lost if corrupted
Subtitle Provider Integrations Connects to 100+ external providers to search and download subtitles No subtitles downloaded; existing subtitles unaffected
Sonarr/Radarr Sync Pulls media library from *arr apps to know what needs subtitles New content not visible to Bazarr; subtitle queue stalls
ffsubsync Engine Audio-based subtitle synchronization using ffmpeg Subtitles download but are out of sync; no hard failure
Plex/Jellyfin Notification Triggers media server refresh after subtitle is added to file Subtitle file present on disk but media server doesn't display it

Uptime History

DateIncident TypeDurationImpact
2026-01 OpenSubtitles API key expiry ~24 hrs undetected All subtitle downloads silently failed; large backlog of unsubtitled content accumulated
2025-10 Sonarr API key rotated without updating Bazarr ~8 hrs New TV episodes not synced to Bazarr; no subtitle jobs created for new content
2025-08 Python dependency conflict after system upgrade ~3 hrs Bazarr Flask app failed to start; web UI and API completely unreachable
2025-07 Multiple providers simultaneously rate limited ~6 hrs Subtitle searches returned zero results across all configured providers

Monitor Bazarr Automatically

Bazarr failures are silent by default — the process may be running while every subtitle provider is rate limited, Sonarr connectivity is broken, or credentials have expired, with no alert sent and subtitles quietly accumulating in the missing queue. ezmon.com monitors your Bazarr endpoints from multiple external probes and alerts your team via Slack, PagerDuty, or SMS the moment the API stops responding or provider health checks fail.

Set up Bazarr monitoring free at ezmon.com →

bazarrsubtitlessonarrradarrself-hostedstatus-checker