Peira Labs

Products

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

CheckFails when
probegluetun or qBittorrent cannot be reached at all
tunnelgluetun reports no public IP, or a private or CGNAT one
port_agreementthe forwarded port and qBittorrent’s listening port disagree
reachabilityqBittorrent reports itself firewalled or disconnected
traffictorrents 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
Example output from the README at commit 27c540d, checked 2026-10-26.

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.