Files
hermes-agent/docs/rca-ssl-cacert-post-git-pull.md
ethernet 547b5de29d docs(pm): route dependency setup through public operations
Direct package installs bypass PM's dependency selection and do not survive
new generations. Document explicit runtime extras, recorded repair, fresh
build outputs, and lock generation through PM instead.

Keep the prepared-interpreter prerequisite and explicit removal requirement
for disposable test environments. Preserve Nix and external-project package
manager ownership. Correct platform and Python-marker claims where the
manifest contradicts the installation hints.

Checked the public CLI help, literal PM calls against public signatures and
extra declarations, fenced blocks, and whitespace. No dependency build or
site build ran. The docs toolchain is not installed in this checkout.
2026-09-11 18:12:49 -04:00

2.6 KiB

RCA: SSL CA cert bundle corruption after hermes update

Status: resolved by fix(ssl): surface broken CA bundles before provider calls Severity: P2 — degrades the agent into opaque provider/client failures until the user repairs deps or CA configuration.

Summary

A partial hermes update, interrupted venv repair, or stale CA-bundle environment variable can leave Python TLS configuration pointing at a missing, empty, or unloadable CA bundle. The first outbound HTTPS client creation or request can then fail with a raw FileNotFoundError: [Errno 2] No such file or directory or a low-level SSL error that does not name the broken CA path.

Root cause

Hermes uses OpenAI/httpx and requests-based clients for provider calls, model metadata, gateway delivery, and web tools. Those clients inherit CA bundle settings from:

  • HERMES_CA_BUNDLE
  • SSL_CERT_FILE
  • REQUESTS_CA_BUNDLE
  • CURL_CA_BUNDLE
  • the bundled certifi package's cacert.pem

When the venv is partially refreshed, or when one of those env vars points at a file that no longer exists, provider client construction can fail before Hermes has enough context to produce a useful message.

Fix

agent/ssl_guard.py validates CA bundle configuration before the OpenAI-compatible provider client is created in agent/agent_init.py. It:

  1. Checks explicit CA bundle env vars and reports the exact broken variable/path,
  2. Verifies certifi is importable,
  3. Verifies certifi.where() points at an existing file of plausible size,
  4. Builds an ssl.SSLContext from each checked bundle,
  5. Raises a typed SSLConfigurationError with a repair hint before httpx/OpenAI can raise a raw low-level error.

hermes_cli doctor exposes the same check under SSL / CA Certificates, so users can diagnose the problem without starting a model session.

Recovery

If the guard reports a broken custom CA path, fix or unset the named variable. For damaged Hermes dependencies, ask PM to rebuild the recorded dependency set:

hermes pm repair

Restart Hermes after a successful repair. Do not modify a selected generation with raw pip or uv commands. For a Nix or sealed installation, rebuild or reinstall through its package owner.

For a custom/corporate CA setup, fix the env var so it points at a real PEM bundle, or unset it if Hermes should use the bundled certifi store.

Environment escape hatch

Set HERMES_SKIP_SSL_GUARD=1 to bypass the preflight check. This is intended only for sandboxed or managed-trust environments where the Python CA path looks unusual but downstream clients are known to work.