hermes - 💡(How to fix) Fix [Bug]: Systemd gateway service exits with status 1 on intentional stop [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Operating System

Raspberry Pi OS Lite 64-bit / Debian 13 trixie, Linux 6.12.75+rpt-rpi-v8 aarch64

Python Version

3.11.15

Hermes Version

Hermes Agent v0.13.0 (2026.5.7), commit dd0923bb8

Additional Logs / Traceback (optional)

Root Cause

A system-level Hermes gateway service stops the process, but systemd records the unit as failed because the gateway exits with status 1.

Fix Action

Fixed

Code Example

sudo env HOME=/home/hermes USER=hermes LOGNAME=hermes HERMES_HOME=/home/hermes/.hermes/profiles/karting \
  /home/hermes/.local/bin/hermes gateway install --system --run-as-user hermes

---

sudo env HOME=/home/hermes USER=hermes LOGNAME=hermes HERMES_HOME=/home/hermes/.hermes/profiles/karting \
  /home/hermes/.local/bin/hermes gateway start --system

---

systemctl show hermes-gateway-karting.service -p ActiveState -p SubState -p Result -p ExecMainStatus

---

sudo env HOME=/home/hermes USER=hermes LOGNAME=hermes HERMES_HOME=/home/hermes/.hermes/profiles/karting \
  /home/hermes/.local/bin/hermes gateway stop --system

---

systemctl show hermes-gateway-karting.service -p ActiveState -p SubState -p Result -p ExecMainCode -p ExecMainStatus

---

sudo systemctl stop hermes-gateway-karting.service

---

ActiveState=inactive
SubState=dead
Result=success
ExecMainStatus=0

### Actual Behavior

Hermes reports the service stopped:

---

But systemd records the unit as failed:

---

The gateway process is gone after the stop, so it does stop, but it exits with failure status.

Direct systemd stop gives the same result:

---

Journal excerpt:

---

### Affected Component

Gateway (Telegram/Discord/Slack/WhatsApp)

### Messaging Platform (if gateway-related)

Telegram

### Debug Report

---

### Operating System

Raspberry Pi OS Lite 64-bit / Debian 13 trixie, Linux 6.12.75+rpt-rpi-v8 aarch64

### Python Version

3.11.15

### Hermes Version

Hermes Agent v0.13.0 (2026.5.7), commit dd0923bb8

### Additional Logs / Traceback (optional)

---

### Root Cause Analysis (optional)

The likely issue is in the planned-stop marker flow for system-level services.

From the code comments, Hermes intentionally exits non-zero for unexpected `SIGTERM` so service managers can revive the gateway. Because service stop commands also send `SIGTERM`, the CLI writes `.gateway-planned-stop.json` before stopping the process so the running gateway can recognise the stop as intentional and exit `0`.

In this repro, `hermes gateway stop --system` creates:

---

but the file is owned by `root:root` with mode `600`, while the systemd service runs as:
RAW_BUFFERClick to expand / collapse

Bug Description

A system-level Hermes gateway service stops the process, but systemd records the unit as failed because the gateway exits with status 1.

This happens during an intentional stop, both with the official Hermes command and with direct systemctl stop.

The gateway itself works normally before and after this. It starts successfully, the Telegram bot replies correctly, and it can be started again after the failed stop state.

Expected: an intentional stop should leave the unit cleanly inactive.

Actual: the process stops, but systemd shows ActiveState=failed, Result=exit-code, and ExecMainStatus=1.

Steps to Reproduce

  1. Install a system-level gateway service for a profile:
sudo env HOME=/home/hermes USER=hermes LOGNAME=hermes HERMES_HOME=/home/hermes/.hermes/profiles/karting \
  /home/hermes/.local/bin/hermes gateway install --system --run-as-user hermes
  1. Start the service:
sudo env HOME=/home/hermes USER=hermes LOGNAME=hermes HERMES_HOME=/home/hermes/.hermes/profiles/karting \
  /home/hermes/.local/bin/hermes gateway start --system
  1. Confirm it is running:
systemctl show hermes-gateway-karting.service -p ActiveState -p SubState -p Result -p ExecMainStatus
  1. Stop it with the official command:
sudo env HOME=/home/hermes USER=hermes LOGNAME=hermes HERMES_HOME=/home/hermes/.hermes/profiles/karting \
  /home/hermes/.local/bin/hermes gateway stop --system
  1. Check systemd state again:
systemctl show hermes-gateway-karting.service -p ActiveState -p SubState -p Result -p ExecMainCode -p ExecMainStatus
  1. Same result also occurs when bypassing the Hermes stop command:
sudo systemctl stop hermes-gateway-karting.service

Expected Behavior

When a system-level gateway service is intentionally stopped, the gateway process should exit cleanly and systemd should record the unit as inactive/successful.

Expected state after stop:

ActiveState=inactive
SubState=dead
Result=success
ExecMainStatus=0

### Actual Behavior

Hermes reports the service stopped:

```text
✓ System service stopped
✓ Stopped hermes-gateway-karting service

But systemd records the unit as failed:

ActiveState=failed
SubState=failed
Result=exit-code
ExecMainCode=1
ExecMainStatus=1

The gateway process is gone after the stop, so it does stop, but it exits with failure status.

Direct systemd stop gives the same result:

sudo systemctl stop hermes-gateway-karting.service

Journal excerpt:

Shutdown context: signal=SIGTERM under_systemd=yes parent_pid=1 parent_name=systemd
Main process exited, code=exited, status=1/FAILURE
Failed with result 'exit-code'.

Affected Component

Gateway (Telegram/Discord/Slack/WhatsApp)

Messaging Platform (if gateway-related)

Telegram

Debug Report

Report       https://paste.rs/FYTii
agent.log    https://paste.rs/0bZ7O
gateway.log  https://paste.rs/g3ztI

Operating System

Raspberry Pi OS Lite 64-bit / Debian 13 trixie, Linux 6.12.75+rpt-rpi-v8 aarch64

Python Version

3.11.15

Hermes Version

Hermes Agent v0.13.0 (2026.5.7), commit dd0923bb8

Additional Logs / Traceback (optional)

Direct `systemctl stop` also reproduces the failed state.


2026-05-12T21:40:39+10:00 systemd[1]: Stopping hermes-gateway-karting.service - Hermes Agent Gateway - Messaging Platform Integration...
2026-05-12T21:40:39+10:00 python[17171]: WARNING gateway.run: Shutdown context: signal=SIGTERM under_systemd=yes parent_pid=1 parent_name=systemd loadavg_1m=0.00 parent_cmdline='/sbin/init'
2026-05-12T21:40:45+10:00 systemd[1]: hermes-gateway-karting.service: Main process exited, code=exited, status=1/FAILURE
2026-05-12T21:40:45+10:00 systemd[1]: hermes-gateway-karting.service: Failed with result 'exit-code'.
2026-05-12T21:40:45+10:00 systemd[1]: Stopped hermes-gateway-karting.service - Hermes Agent Gateway - Messaging Platform Integration.
`

Observed machine state after stop:


MainPID=0
Result=exit-code
ExecMainCode=1
ExecMainStatus=1
ActiveState=failed
SubState=failed

Root Cause Analysis (optional)

The likely issue is in the planned-stop marker flow for system-level services.

From the code comments, Hermes intentionally exits non-zero for unexpected SIGTERM so service managers can revive the gateway. Because service stop commands also send SIGTERM, the CLI writes .gateway-planned-stop.json before stopping the process so the running gateway can recognise the stop as intentional and exit 0.

In this repro, hermes gateway stop --system creates:

/home/hermes/.hermes/profiles/karting/.gateway-planned-stop.json

but the file is owned by root:root with mode 600, while the systemd service runs as:

User=hermes
Group=hermes

So the gateway process likely cannot read/consume the planned-stop marker, treats the SIGTERM as unexpected, and exits with status 1.

Direct sudo systemctl stop hermes-gateway-karting.service also exits 1, which makes sense with this design because no Hermes planned-stop marker is written before systemd sends SIGTERM.

Proposed Fix (optional)

For hermes gateway stop --system, ensure the planned-stop marker is created in a way the runtime service user can read and consume it.

Possible fixes:

  • write .gateway-planned-stop.json as the configured service user, not root
  • or chown/chmod the marker so User=hermes can read/remove it
  • optionally update the generated systemd unit to handle direct systemctl stop cleanly, for example through a non-recursive ExecStop helper that marks the stop as planned before signalling the gateway

I would avoid simply adding SuccessExitStatus=1, because that may hide genuine unexpected SIGTERM failures that Hermes currently appears to use for service-manager recovery.

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING