Hermes Agent Gateway: When Messages Don't Arrive
A troubleshooting reference for the Hermes messaging gateway: token/allow-list, adapter, runtime, routing — separating failures by cheap-first check order when the bot doesn't respond.

The most common gateway failure has one shape: “I sent a message and the bot didn’t respond.” Everything else — the daemon, the agent, the model, the adapter, the network — is upstream of that symptom. This guide gives a cheap-first check order that, in under a minute, tells you which layer is broken. It is the troubleshooting companion to the gateway Telegram setup guide.
The five layers to check
Each layer sits between the operator’s Telegram client and the agent chat. Fix in this order — cheapest first, most invasive last.
- Bot token — does the Telegram credential still identify a real bot?
- Chat allow-list — is the channel ID you are messaging from actually permitted?
- Adapter connection — is the gateway’s Telegram adapter actually polling Telegram?
- Hermes runtime — is the local agent reachable from the gateway when a message lands?
- Routing — when the agent replies, does the reply actually land back in Telegram?
If layer 1 is broken, no command in your terminal will produce a reply. If layer 5 is broken, the agent is talking to itself and you just cannot see it. Most operators start at the layer they know best — usually the agent — instead of the outside.
Start with the symptom
Match what you see in Telegram to the row that fits, then run the cheap-first check. The “Confirms” column tells you which layer you are on.
| # | Symptom | Cheap-first check | Confirms |
|---|---|---|---|
| 1 | Bot shows “deleted” / “can’t access” | curl .../bot<token>/getMe | Token (200 vs 401/404) |
| 2 | Bot online but ignores every message | hermes gateway status --deep --platform telegram | Allow-list matches chat ID |
| 3 | Adapter logs 401/429/timeout | hermes gateway run foreground | Network/token/limit |
| 4 | Adapter connected, no reply | hermes gateway status --system | Agent reachable? |
| 5 | Reply in logs, not in Telegram | hermes gateway list + allowed_chats | Outbound routing wired |
| 6 | Slow reply, eventually arrives | hermes gateway status --system | Runtime queue slowness |
| 7 | Replies once, then silent ~5 min | hermes gateway status --deep --platform telegram | Telegram 429 backoff |
Do not start with hermes gateway restart until row 1 is answered, because a restart cannot fix a wrong token.
Layer 1: the bot token
curl -sS https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getMe is the cheapest possible check. Telegram returns JSON; a clean reply looks like {"ok":true,"result":{...}}. Three outcomes:
- HTTP 200 with
ok:true— token identifies a real bot. Move to Layer 2. - HTTP 401 — token rejected. Either the env var is unset in the gateway’s shell, or @BotFather rotated the token. Get a fresh one and re-run
hermes gateway setup. - HTTP 404 — bot was deleted, or the token is malformed (extra whitespace, missing digits, wrong
botprefix). A 404 is a token problem, not a network problem.
There is no recovery for a deleted bot other than creating a new one and redoing setup.
Layer 2: the chat allow-list
Once the token is good, the next gate is whether the channel you are messaging from is in the allow-list. On this home setup the channel ID is 8630382972.
hermes gateway status --deep --platform telegram
When the allow-list includes the home channel, the output shows a line like home_chat_id: 8630382972 allowed. When it does not, the same block either omits the line or shows not_allowed. The gateway is working as designed; it is just refusing to talk to your chat. Fix:
hermes gateway setup
# add 8630382972 (or your channel) to the allow-list
# restart the gateway
Do not add every chat ID you find. The allow-list is the safety boundary that keeps a leaked token from being used to talk to arbitrary people.
Layer 3: the adapter connection
With token and allow-list correct, the question is whether the gateway’s Telegram adapter is actually polling Telegram. Run the gateway in the foreground to see the log line:
hermes gateway run
A healthy adapter logs telegram: connected to polling endpoint shortly after start. An unhealthy adapter logs one of three shapes:
telegram: 401 Unauthorized— token rotated or revoked. Re-run Layer 1’s fix.telegram: 429 Too Many Requests— Telegram rate-limited the long-poll. The adapter should back off; if it does not, reduce the number of channels polling from the same IP.telegram: timeout / connection reset— network or firewall. Verify withcurl -sS https://api.telegram.org/from the same host.
If the adapter log is silent (no “connected”, no error), the gateway started but never reached the platform — usually a setup-file problem. hermes gateway setup again, and confirm the platform shows up in ~/.hermes/channel_directory.json.
Layer 4: the Hermes runtime
If the adapter is connected and the gateway logs a received message, but no reply is produced, the chat runtime is at fault — the adapter is doing its job, the agent is not. The cheap check is:
hermes gateway status --system
On a healthy host (this VPS, 2026-07-14, Hermes v0.18.2) that prints:
✓ Gateway is running (PID: 1170436)
(Running manually, not as a system service)
To install as a service:
hermes gateway install
sudo hermes gateway install --system
For a runtime check, the relevant line is the agent: reachable indicator (or its absence). If it is missing or says unreachable, the gateway is up but cannot dispatch to a model session. Common causes: model provider down, expired API key, endpoint changed, or a runtime that crashed and was not auto-restarted. Confirm the standalone CLI chat still works (hermes chat -q "Reply with OK."); if it does, the runtime is fine and the problem is one layer up.
Layer 5: routing
The final layer is the one operators forget: the agent produces a reply, the gateway accepts it, and the reply must be sent back to the same Telegram chat it came from. If the reply exists in logs but never appears in Telegram, routing is broken. Check:
hermes gateway listshows the channel.- The platform entry has a non-empty
allowed_chatscontaining8630382972. - The outbound side of the adapter log shows a
sendMessagecall with the correctchat_id.
A wiring mismatch (chat ID in the inbound allow-list but not in the outbound router, or vice versa) is the most common cause. Re-run hermes gateway setup and confirm both sides are populated.
Common failures
| # | Symptom | Layer | First command | Fix |
|---|---|---|---|---|
| 1 | getMe returns 401 | 1 | curl .../getMe | New token from @BotFather, re-run hermes gateway setup |
| 2 | getMe returns 404 | 1 | same | Verify token shape; recreate the bot if deleted |
| 3 | Bot online, ignores all messages | 2 | hermes gateway status --deep --platform telegram | Add 8630382972 to allow-list |
| 4 | Adapter log: 429 | 3 | foreground hermes gateway run | Reduce poll count per IP; wait for backoff |
| 5 | Adapter log: timeout | 3 | curl -sS https://api.telegram.org/ from host | Fix network/firewall; check egress to Telegram |
| 6 | Adapter connected, no reply | 4 | hermes gateway status --system | Confirm model session alive; restart runtime if needed |
| 7 | Reply in logs, not in Telegram | 5 | hermes gateway list | Re-run hermes gateway setup, verify outbound chat ID |
| 8 | ”Bot token already in use (PID NNNN)” where NNNN is a defunct process | 3 | ps -o pid,stat -p NNNN | Previous gateway child died uncleanly; lock-holder is a zombie. kill NNNN does nothing on zombies — clean up with hermes gateway uninstall && hermes gateway install, then restart. The watchdog installed 2026-06-05 auto-detects polling wedges (CLOSE_WAIT>=3 or getUpdates probe>8s on 60s) but does not auto-reap zombies; manual clean is still needed. |
What not to do
- Do not keep retrying setup for the same bot without first checking the token. A wrong token fails the same way every time, and the symptom is upstream of anything setup can fix.
- Do not open Telegram and assume the bot did not get the message. Check the adapter log first; Telegram can show “delivered” for messages a long-poll never picked up.
- Do not enable debug logging on the gateway without sanitizing.
-v/-vvcan include message bodies. Strip PII or redirect to a private log file before turning it on in production.
Verification checklist
| # | Command | What it proves |
|---|---|---|
| 1 | curl api.telegram.org/bot<token>/getMe | Token valid |
| 2 | hermes gateway list | Gateway instance (and platform) registered |
| 3 | hermes gateway status --deep --platform telegram | Adapter healthy, home chat allowed |
| 4 | hermes gateway status --system | Agent runtime reachable from gateway |
| 5 | Send a message; reply arrives within 30s | End-to-end loop working |
If all five pass, the gateway is healthy and the problem is not in this stack.
Sources
- Hermes messaging docs
- ABS companion: Hermes Gateway Telegram Setup
- ABS troubleshooting reference: ABS Regression Failure Modes
Last verified: 2026-07-14 against Hermes v0.18.2 (2026.7.7.2) and home Telegram channel ID 8630382972.


Submit a take
Have a different read on this? Drop a comment below — your email isn't published, and I read every one. Nothing leaves the site until I approve it.