NousResearch/hermes-agent · error · RuntimeError
iron-proxy config not found at {cfg}. Run `hermes egress set
Error message
iron-proxy config not found at {cfg}. Run `hermes egress setup` first. What it means
start_proxy() requires proxy.yaml to exist (defaulting to <proxy state dir>/proxy.yaml, or the config_path argument) because it never launches the daemon with an implicit config. The message names the exact path checked and the setup command that generates it. It fires only after the binary was successfully resolved, so it's purely the 'setup not run on this machine/profile' precondition.
Source
Thrown at agent/proxy_sources/iron_proxy.py:1795
Without this flag (or with ``bitwarden_config=None``) the proxy still
starts but uses whatever the host process env happens to contain.
"""
global _proxy_nonce
existing = _read_pid()
if existing and _pid_alive(existing):
return get_status()
bin_path = binary or find_iron_proxy(install_if_missing=install_if_missing)
if bin_path is None:
raise RuntimeError(
"iron-proxy binary not available — run `hermes egress install`."
)
cfg = config_path or (_proxy_state_dir() / "proxy.yaml")
if not cfg.exists():
raise RuntimeError(
f"iron-proxy config not found at {cfg}. "
"Run `hermes egress setup` first."
)
# Build a minimal subprocess env. os.environ.copy() would ship every
# secret in the operator's shell to the proxy — /proc/<pid>/environ
# would then expose OPENAI_API_KEY, AWS keys, etc. to any same-uid
# local process. Defeats the threat model the proxy exists to
# mitigate.
env = _build_proxy_subprocess_env(
extra_env=extra_env,
refresh_from_bitwarden=refresh_secrets_from_bitwarden,
bitwarden_config=bitwarden_config,
)
# If the generated config enables the management API, the daemon
# validates at startup that the api_key_env is non-empty. Inject the
# persisted key (minting it if this is a config written by a newerView on GitHub (pinned to c896c09c42)
Solutions
- Run `hermes egress setup` to generate proxy.yaml (plus CA cert) for this profile.
- If passing config_path explicitly, verify the path exists and is readable before starting.
- Remember state is per-profile under HERMES_HOME — setup must be re-run per profile.
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
from agent.proxy_sources.iron_proxy import _proxy_state_dir
def proxy_config_exists() -> bool:
return (_proxy_state_dir() / "proxy.yaml").exists() Try / catch
try:
start_proxy()
except RuntimeError as e:
if "config not found" in str(e):
# run hermes egress setup, then retry
raise Prevention
- Run `hermes egress setup` once per profile (state dirs are per-HERMES_HOME).
- When passing config_path explicitly, assert it exists before starting.
When it happens
Trigger: start_proxy() / `hermes egress start` when `hermes egress setup` was never run on this HERMES_HOME, the proxy state dir was wiped, or a custom config_path was passed that doesn't exist (typo, wrong profile).
Common situations: Fresh installs; switching to a new Hermes profile (each profile has its own state dir); passing a stale config_path from automation after the file moved.
Related errors
- iron-proxy is not running — nothing to reload. Run `hermes
- The generated proxy.yaml has no management listener (written
- management.token is missing — re-run `hermes egress setup`,
- iron-proxy rejected the new config (validation failed; the r
- management API rejected our key (401). The running daemon w
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/e425c37735065e53.
Report an issue: GitHub.