NousResearch/hermes-agent · warning · RuntimeError
management API rejected our key (401). The running daemon w
Error message
management API rejected our key (401). The running daemon was started with a different management.token — run `hermes egress restart`.
What it means
reload_proxy() authenticates to /v1/reload with the management.token from the on-disk config. HTTP 401 means the running daemon was started with a different token — most commonly because setup regenerated the token after the daemon was last started. The daemon's token can't be hot-swapped, so the fix is a restart under the current config.
Source
Thrown at agent/proxy_sources/iron_proxy.py:977
with urllib.request.urlopen(req, timeout=_MGMT_RELOAD_TIMEOUT) as resp:
if resp.status == 200:
return True
raise RuntimeError(
f"management API returned unexpected status {resp.status}"
)
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]:View on GitHub (pinned to c896c09c42)
Solutions
- Run `hermes egress restart` so the daemon starts with the current management.token, then reload future changes normally.
- Make it a habit: after any `hermes egress setup`, restart once before relying on reload.
- If using custom config_path, make sure you reload the same config the daemon was started with.
Defensive patterns
Strategy: try-catch
Try / catch
try:
reload_proxy()
except RuntimeError as e:
if "401" in str(e):
# token rotated since daemon start — one restart re-syncs it
raise Prevention
- Pair every `hermes egress setup` with a restart before subsequent reloads.
- Don't run the daemon from one config/state dir while reloading against another.
When it happens
Trigger: reload_proxy() / `hermes egress reload` after re-running `hermes egress setup` (which rotates management.token) without restarting the daemon; or two configs / two state dirs where the daemon was started from a different one.
Common situations: Re-running setup to change rules and forgetting restart; running multiple profiles whose proxy state dirs got crossed; manually starting the daemon with an explicit config_path and later reloading with the default config.
Related errors
- management.token is missing — re-run `hermes egress setup`,
- The generated proxy.yaml has no management listener (written
- iron-proxy rejected the new config (validation failed; the r
- iron-proxy is not running — nothing to reload. Run `hermes
- management API returned unexpected status {resp.status}
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/28252053991bfff3.
Report an issue: GitHub.