You set up a Telegram bot in Hermes Agent, restart the gateway and the log shows:
ERROR gateway.run: Gateway failed to connect any configured messaging platform:
telegram: Telegram startup failed: The token '8765418140:***' was rejected by the server.
First instinct is to assume the token is wrong. In my experience, 7 times out of 10 the actual cause is that you're editing the wrong config file. The token in BotFather works fine, Hermes is just loading a stale value.
Step 1: Verify the token works directly
Test the token against Telegram's API using curl. This isolates if the token is genuinely wrong or if Hermes is just sending an old one.
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getMe"
Response with "ok": true and your bot's username: token works, Hermes is sending the wrong value.
Response with "ok": false and "description": "Unauthorized": token genuinely doesn't work. Open BotFather, run /mybots, pick the bot, choose API Token, regenerate or verify.
Step 2: Find which config Hermes is reading
Hermes can read the Telegram token from three different places:
~/.hermes/.env~/.hermes/config.yaml- Environment variable in the shell that runs the gateway
The wizard you ran during setup wrote it to one of these. If you edited a different file later thinking you were updating the token, you weren't. The old value is still being loaded.
Check all three sources
hermes gateway config show | grep -i telegram
grep -i TELEGRAM ~/.hermes/.env 2>/dev/null
grep -i telegram ~/.hermes/config.yaml 2>/dev/null
env | grep TELEGRAM
You want exactly one source of truth. If two sources both have a token and they don't match, Hermes picks one based on load order. That might not be the one you edited.
Step 3: Update the token through the CLI
Don't hand-edit .env or config.yaml unless you know exactly where Hermes is reading from. Use the CLI which writes to the canonical location:
hermes gateway set telegram --token "8765418140:AAA..."
hermes gateway restart telegram
hermes gateway status
If status shows telegram connected, you're done. If it still says token rejected, the CLI wrote to the right location but Hermes is loading from somewhere else. Almost always means you have two Hermes installs on the same machine (one in ~/.local/bin, one elsewhere) reading conflicting configs.
which hermes
hermes --version
Clean up the stale install. See our hermes command not found piece for the cleanup pattern.
The "Unauthorized" log variant
If the log shows Unauthorized rather than "token rejected", three possible causes:
Token was revoked
Regenerate in BotFather and update Hermes through the CLI command above.
Token is correct but Hermes can't reach Telegram
Network blocked. Firewall rules. Container without outbound access.
curl -s -o /dev/null -w "%{http_code}\n" https://api.telegram.org/
200 or 401 means Telegram is reachable. Anything else (timeout, DNS error, 403): network problem, not token problem.
Whitespace in the pasted token
Leading or trailing space from a bad paste makes Telegram reject it. Re-paste through the CLI to be safe.
Bot connects but ignores your messages (allowlist issue)
The gateway connects cleanly to Telegram but the bot doesn't respond when you message it. Different problem. Bot is alive, you're just not on the allowlist.
Find your Telegram user ID
Message @userinfobot on Telegram. It tells you your numeric user ID.
Add yourself to the allowlist
hermes gateway allowlist add telegram 123456789
Open mode (testing only)
hermes gateway allowlist set telegram open
Anyone with your bot's username can now message it. Don't run open mode in production. Public bot with no allowlist racks up token costs fast.
After regenerating the token in BotFather
The old token is permanently dead. Anything with a copy needs updating:
- ~/.hermes/.env on the box running Hermes
- systemd unit's Environment= lines if you embedded it there
- Docker compose file if you pass it in there
- Any backup file you might restore from
- Your password manager entry
Find and update everywhere:
grep -rIn "8765418140" ~/.hermes/ 2>/dev/null
sudo grep -rIn "8765418140" /etc/systemd/system/ 2>/dev/null
(Use the first part of the old token in the search, not the full token. Obvious security reasons.)
Keep the token out of version control
For production setups, don't commit the token to a config repo. Use a secrets manager (systemd-creds, sops, your cloud provider's secrets API) and have Hermes read from there. Production patterns covered in our Hermes production hardening guide.
For homelab use, an .env file outside the repo with chmod 600 is enough. Don't share it.
Where Telegram fits in a wider setup
Once Telegram works, the natural next steps:
- Adding a second channel: see multi-platform gateway tutorial
- Tightening security: see production hardening
- Managing token costs for a busy bot: see Hermes token costs
Pre-configured Telegram on LumaDock
The Hermes Agent template on LumaDock has the gateway preinstalled with the Telegram setup wizard ready to run. Walks you through token entry, allowlist and smoke test in one flow. Unmetered bandwidth (matters when your bot is in busy channels) and no setup fees. Complete template details in our Hermes Agent complete guide.

