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 newer

View on GitHub (pinned to c896c09c42)

Solutions

  1. Run `hermes egress setup` to generate proxy.yaml (plus CA cert) for this profile.
  2. If passing config_path explicitly, verify the path exists and is readable before starting.
  3. 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

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


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