deadair
Checks whether a gluetun and qBittorrent stack is actually working, not merely configured.
- Status
- Released v0.1.1 on 2026-09-28
- License
- Apache-2.0 or MIT
- Get it
- Source and README · static binaries · container image for linux/amd64 and linux/arm64
The gap it fills
Several tools copy gluetun’s forwarded port into qBittorrent, and once the port matches they report success. A matching port is a statement about configuration. The tunnel can drop, the port can stop being reachable from outside, or peers can disappear, and the sync still looks clean while nothing downloads. deadair checks the traffic side, and stays quiet when the queue is simply idle, so it is safe to alert on.
The five checks
| Check | Fails when |
|---|---|
probe | gluetun or qBittorrent cannot be reached at all |
tunnel | gluetun reports no public IP, or a private or CGNAT one |
port_agreement | the forwarded port and qBittorrent’s listening port disagree |
reachability | qBittorrent reports itself firewalled or disconnected |
traffic | torrents want data and no bytes arrived within the stall window |
When sampling over time, a failure on one sample is reported as a warning until it repeats for a set number of samples in a row, so one blip does not page anyone. A one-shot deadair check has no history and reports a failure at once; it exits 0, 1 or 2 for ok, warn and fail. deadair watch serves Prometheus metrics and a /healthz that answers 200 or 503.
[ok] probe all probes succeeded
[ok] tunnel 203.0.113.42
[fail] port_agreement forwarded 51413, listening 6881
[fail] reachability firewalled
[fail] traffic 3 torrents want data; 0 bytes in 900s
[fail] overall
What it does not do
deadair does not sync the forwarded port and does not change qBittorrent’s settings. It only reads; the one write it makes is the WebUI login it needs in order to read. Keep whichever port syncer you already run: deadair tells you when that syncer’s work stopped being enough.