Problem or Use Case
I’m running Hermes dashboard behind a Traefik reverse proxy and the dashboard UI works great, but Chat fails because the dashboard websocket endpoints are rejected with 4403 client_host_not_loopback.
Environment
- Hermes Agent version: v0.12.0 (2026.4.30)
- Dashboard launched via a systemd user service
- Reverse proxy: Traefik
- Hermes agent, hermes dashboard and Traefik proxy are on the same host server
- Browser connects to:
https://hermes.local.anondomain.com
- Traefik proxies to:
- Dashboard access, via proxy, limited to authenticated users by Authentik.
Symptoms
Browser console shows websocket failures for:
/api/ws
/api/events
/api/pty
Example frontend error:
events feed disconnected — tool calls may not appear
What I've tested
-
Dashboard dependencies are installed and working
-
Normal dashboard pages load correctly
-
Tried different dashboard arguments including:
--host 127.0.0.1 --port 9119 --no-open
--host 0.0.0.0 --port 9119 --no-open --insecure
-
Set Traefik passHostHeader: false
-
Verified upstream requests from the Traefik proxy use:
TCPDUMP packet capture / proxy evidence
Traefik forwards websocket upgrade requests like:
http
GET /api/ws?... HTTP/1.1
Host: 127.0.0.1:9119
Connection: Upgrade
Upgrade: websocket
X-Forwarded-For: 192.168.xx.xx # anonymised laptop IP
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Real-Ip: 127.0.0.1
Hermes responds with 403 Forbidden.
Added temporary logging to Hermes web server
I temporarily added logging to hermes_cli/web_server.py and captured:
Dashboard websocket close: endpoint=/api/ws code=4403 reason=client_host_not_loopback ctx={
'path': '/api/ws',
'client_host': '192.168.10.70',
'client_port': 0,
'host': '127.0.0.1:9119',
'origin': 'https://hermes.local.anondomain.com', # anonymised
'x_forwarded_for': '192.168.xx.xx', # anonymised laptop IP
'x_real_ip': '127.0.0.1',
'x_forwarded_host': '',
'x_forwarded_proto': 'https',
'x_forwarded_port': '443',
'upgrade': 'websocket',
'connection': 'Upgrade',
'has_token': True,
'token_prefix': '3M2pQKH_',
'channel': ''
}
Similar entries occur for:
Root cause
The dashboard websocket handlers reject when:
client_host = ws.client.host if ws.client else ""
if client_host and client_host not in _LOOPBACK_HOSTS:
await ws.close(code=4403)
In a reverse proxy deployment, ws.client.host becomes the original browser IP rather than loopback, so chat is unusable even when the reverse proxy is on the same host and the upstream target is 127.0.0.1.
Proposed Solution
Please make Hermes dashboard chat usable behind a trusted reverse proxy, for example by one of:
- making the loopback-only websocket restriction configurable
- disabling proxy-derived client-IP enforcement for dashboard websocket endpoints
- using a different trust model when the dashboard is intentionally run with
--insecure
- allowing trusted same-host reverse proxy deployments explicitly
Alternatives Considered
I've tried many different configurations to 'trick' the Hermes web server to no avail.
I don't want to add a messaging gateway to all Hermes profiles (those with sandboxed BE's already have messaging) or to install a desktop and browser on the server to access dashboard chat. There may be different proxies that can handle it differently but I believe this is a sensible change that other users may need.
Feature Type
Configuration option
Scope
None
Contribution
Debug Report (optional)
Problem or Use Case
I’m running Hermes dashboard behind a Traefik reverse proxy and the dashboard UI works great, but Chat fails because the dashboard websocket endpoints are rejected with
4403 client_host_not_loopback.Environment
https://hermes.local.anondomain.comhttp://127.0.0.1:9119Symptoms
Browser console shows websocket failures for:
/api/ws/api/events/api/ptyExample frontend error:
events feed disconnected — tool calls may not appearWhat I've tested
Dashboard dependencies are installed and working
Normal dashboard pages load correctly
Tried different dashboard arguments including:
--host 127.0.0.1 --port 9119 --no-open--host 0.0.0.0 --port 9119 --no-open --insecureSet Traefik passHostHeader: false
Verified upstream requests from the Traefik proxy use:
127.0.0.1:9119TCPDUMP packet capture / proxy evidence
Traefik forwards websocket upgrade requests like:
Hermes responds with
403 Forbidden.Added temporary logging to Hermes web server
I temporarily added logging to
hermes_cli/web_server.pyand captured:Similar entries occur for:
/api/events/api/ptyRoot cause
The dashboard websocket handlers reject when:
In a reverse proxy deployment,
ws.client.hostbecomes the original browser IP rather than loopback, so chat is unusable even when the reverse proxy is on the same host and the upstream target is127.0.0.1.Proposed Solution
Please make Hermes dashboard chat usable behind a trusted reverse proxy, for example by one of:
--insecureAlternatives Considered
I've tried many different configurations to 'trick' the Hermes web server to no avail.
I don't want to add a messaging gateway to all Hermes profiles (those with sandboxed BE's already have messaging) or to install a desktop and browser on the server to access dashboard chat. There may be different proxies that can handle it differently but I believe this is a sensible change that other users may need.
Feature Type
Configuration option
Scope
None
Contribution
Debug Report (optional)