NousResearch/hermes-agent · error · RuntimeError

management reload failed (HTTP {exc.code}): {body}

Error message

management reload failed (HTTP {exc.code}): {body}

What it means

Catch-all for management-API HTTP errors other than 422 (validation) and 401 (token mismatch) during POST /v1/reload — e.g. 404 (endpoint missing on this daemon version), 500 (daemon bug), 503 (shutting down). The error includes the HTTP code and up to 500 bytes of the response body for diagnosis. The running ruleset state depends on the code: a 5xx mid-swap is the risky one.

Source

Thrown at agent/proxy_sources/iron_proxy.py:982

            )
    except urllib.error.HTTPError as exc:
        body = ""
        try:
            body = exc.read().decode("utf-8", errors="replace")[:500]
        except OSError:
            pass
        if exc.code == 422:
            raise RuntimeError(
                f"iron-proxy rejected the new config (validation failed; "
                f"the running ruleset is unchanged): {body}"
            ) from exc
        if exc.code == 401:
            raise RuntimeError(
                "management API rejected our key (401).  The running "
                "daemon was started with a different management.token — "
                "run `hermes egress restart`."
            ) from exc
        raise RuntimeError(
            f"management reload failed (HTTP {exc.code}): {body}"
        ) from exc
    except (urllib.error.URLError, OSError) as exc:
        # A daemon started from a pre-management config is alive but has
        # no listener on the management port.
        raise RuntimeError(
            f"could not reach the management API at {host}:{port} ({exc}).  "
            "If the daemon was started before reload support, run "
            "`hermes egress restart` once."
        ) from exc


def _default_http_listen(tunnel_port: int) -> List[str]:
    """Build the single host:port bind the proxy should listen on.

    iron-proxy v0.39 supports exactly ONE ``proxy.http_listen`` bind per
    daemon process, so this returns a one-element list and the choice of
    host matters:

View on GitHub (pinned to c896c09c42)

Solutions

  1. Decode the status: 404 → the daemon build lacks reload support, `hermes egress restart` instead; 5xx → check iron-proxy.log and the daemon's health before retrying.
  2. Re-align versions with `hermes egress install` + restart so the daemon matches the client's expectations.
  3. After any 5xx reload, verify with get_status() which ruleset is actually running before re-attempting.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    reload_proxy()
except RuntimeError as e:
    if "management reload failed" in str(e):
        # inspect code+body; 404 → restart instead, 5xx → check daemon health
        raise

Prevention

When it happens

Trigger: reload_proxy() against a daemon version that predates /v1/reload but does expose the management listener (404), a daemon crash mid-reload (5xx), or internal errors from a malformed-but-schema-valid config.

Common situations: Version skew between the iron-proxy binary and the Hermes client; a daemon that is being shut down concurrently; resource exhaustion inside the daemon.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/df4c1deaeca0bf1f. Report an issue: GitHub.