ArchiveBox/ArchiveBox · error · RuntimeError

Refusing to start a nested supervisord; inherited supervisor

Error message

Refusing to start a nested supervisord; inherited supervisor is unavailable at unix://{SOCK_FILE}

What it means

get_or_create_supervisord_process first tries get_existing_supervisord_process(). If none is reachable but SUPERVISOR_SERVER_URL is set in the environment, it means this process was spawned by a supervisord whose socket it can no longer connect to; it raises rather than starting a competing daemon.

Source

Thrown at archivebox/workers/supervisord_util.py:1008

    """Poll for supervisord readiness without a fixed startup sleep."""
    deadline = time.monotonic() + max_wait_sec
    supervisor = None
    while time.monotonic() < deadline:
        supervisor = get_existing_supervisord_process(quiet=quiet)
        if supervisor is not None:
            return supervisor
        time.sleep(interval_sec)
    return supervisor


def get_or_create_supervisord_process(daemonize=False):
    SOCK_FILE = get_sock_file()
    WORKERS_DIR = SOCK_FILE.parent / WORKERS_DIR_NAME

    supervisor = get_existing_supervisord_process()
    if supervisor is None:
        if os.environ.get("SUPERVISOR_SERVER_URL"):
            raise RuntimeError(f"Refusing to start a nested supervisord; inherited supervisor is unavailable at unix://{SOCK_FILE}")
        stop_existing_supervisord_process()
        supervisor = start_new_supervisord_process(daemonize=daemonize)

    if supervisor is None:
        raise RuntimeError("Failed to start supervisord or connect to it")
    supervisor.getPID()  # make sure it doesn't throw an exception

    (WORKERS_DIR / "initial_startup.conf").unlink(missing_ok=True)

    return supervisor


def start_worker(supervisor, daemon, lazy=False):
    existing = get_worker(supervisor, daemon["name"])
    if isinstance(existing, dict) and existing.get("statename") in ("STARTING", "RUNNING"):
        return existing
    return sync_supervisord_workers(supervisor, [(daemon, lazy)], prune=False).get(daemon["name"])

View on GitHub (pinned to 74564b2822)

Solutions

  1. Verify the socket path from SUPERVISOR_SERVER_URL exists and is connectable; restart the parent supervisord so the socket is recreated
  2. Point SUPERVISOR_SERVER_URL / ArchiveBox worker dir config to the correct, matching socket path
  3. Remove stale socket files in the workers dir and restart the daemon stack from a top-level command (`archivebox server`)
  4. Unset SUPERVISOR_SERVER_URL only if this process is truly standalone and should own a fresh supervisord

Example fix

// before: inherited URL points at dead socket
SUPERVISOR_SERVER_URL=unix:///old/hash/supervisor.sock archivebox run
// after
ls data/workers/*.sock  # find current socket
export SUPERVISOR_SERVER_URL=unix://<current>/supervisor.sock
archivebox run
Defensive patterns

Strategy: validation

Validate before calling

import os, socket
url = os.environ.get('SUPERVISOR_SERVER_URL', '')
if url.startswith('unix://'):
    sock = url[len('unix://'):]
    if not os.path.exists(sock):
        # inherited supervisor socket is gone; fix env or restart the daemon stack first
        raise SystemExit(f'SUPERVISOR_SERVER_URL points at missing socket: {sock}')
    s = socket.socket(socket.AF_UNIX); s.connect(sock); s.close()

Try / catch

try:
    supervisor = get_or_create_supervisord_process()
except RuntimeError as e:
    if 'inherited supervisor is unavailable' in str(e):
        print('parent supervisord socket dead; restarting daemon stack from top level')
        os.environ.pop('SUPERVISOR_SERVER_URL', None)
        supervisor = get_or_create_supervisord_process()
    else:
        raise

Prevention

When it happens

Trigger: Calling get_or_create_supervisord_process (from ensure_daemon_stack, run_runner_worker, start_server_workers) in a process with SUPERVISOR_SERVER_URL set while the inherited supervisord is down, crashed, or its unix socket path is stale/mismatched.

Common situations: Parent supervisord restarted and socket file recreated with different path/hash; worker running in a container where the parent's socket isn't mounted; supervisord killed uncleanly leaving a dead socket; mismatched ARCHIVEBOX_WORKER_DIR between parent and child.

Related errors


AI-assisted analysis of ArchiveBox/ArchiveBox@74564b2822 (2026-08-28). Data as JSON: /api/errors/51638e0dc2e0df89. Report an issue: GitHub.