License Heartbeat & Grace Period

How Commander's license heartbeat works, what the four grace states mean, and how to recover from WARN or HALTED.

If you landed here from a yellow, orange, or red banner in your Commander dashboard — or from a Telegram alert — this page tells you exactly what's happening and what to do next.

In short: your Commander worker on your VPS hasn't been able to confirm its license with runcommander.com recently. Your runs aren't lost, and in most cases nothing has actually broken yet. This doc walks through the four states the system can be in, the usual causes, and a one-minute test you can run to confirm whether the heartbeat is reaching us.

The four heartbeat states

Every Commander worker calls home on a short interval and records the time of its last successful response. From that timestamp, the worker derives one of four states. The state determines how the worker behaves and which banner you see.

OK

Last successful heartbeat: less than 24 hours ago.

This is the normal state. Runs start and complete as scheduled. You will not see any banner or alert. Nothing for you to do.

WARN_1 — yellow

Last successful heartbeat: between 24 and 48 hours ago.

The worker is still fully operational. Runs continue to start and complete normally. The yellow banner is informational — we want you to know that we have not heard from your worker in a day, so you can investigate at your convenience. The worker keeps retrying automatically in the background. If the next heartbeat succeeds, the banner clears immediately.

WARN_2 — orange

Last successful heartbeat: between 48 and 72 hours ago.

Same operational behavior as WARN_1 — runs continue normally — but the tone escalates. At the 72-hour mark, the worker will refuse to start new runs. In-flight runs will still finish. This is your last warning to act before that happens. Most cases at this point are unattended network or DNS issues on the VPS that are easy to fix once spotted.

HALTED — red

Last successful heartbeat: 72 hours or more ago.

The worker will not start new runs. Runs already in progress when the state flipped continue to completion — Commander never kills mid-flight work. As soon as a single heartbeat succeeds again, the state clears atomically and new runs resume on the next schedule tick. There is no manual unlock needed and no penalty period.

Common causes

In rough order of frequency, here is what usually causes a heartbeat to fail:

  • VPS network blip. Transient packet loss, brief upstream outage at your VPS provider, or a DNS hiccup. Most of these recover on their own within minutes; you may see WARN_1 briefly and then nothing.
  • Firewall or egress rule change. Someone added an outbound block, a new security group, or a UFW rule that no longer allows HTTPS to runcommander.com. Common right after server hardening or migration.
  • Expired or rotated license token. If your token was rotated in the dashboard but the new value never landed in ~/.commander/license.token on the VPS, every heartbeat will fail authentication. Check the worker logs for a 401 response.
  • Billing failure. If your subscription lapsed, the license server will reject heartbeats with a clear state: REVOKED response. Your Commander dashboard will show the billing issue directly — fix the payment method and the license becomes active again within seconds.
  • Clock skew on the VPS. Rare, but a VPS clock more than a few minutes off can break TLS handshakes against our edge. timedatectl status will tell you.

Test the heartbeat manually

If you have shell access to the VPS running your Commander worker, this one-minute test confirms whether the heartbeat round-trip works end-to-end. It uses the same token and fingerprint the worker uses.

# 1. Get your stored license token
cat ~/.commander/license.token

# 2. Get your worker fingerprint
cat ~/.commander/fingerprint

# 3. POST it to the license server
curl -sX POST \
  -H "authorization: Bearer $(cat ~/.commander/license.token)" \
  -H "content-type: application/json" \
  -d "{\"fingerprint\":\"$(cat ~/.commander/fingerprint)\",\"agentVersion\":\"0.0.1\"}" \
  https://runcommander.com/api/license/heartbeat | jq .

# Expected: { "ok": true, "state": "OK", "secondsSinceLastSuccess": 0, ... }

Interpret the result:

  • A response with "ok": true and "state": "OK" means the round-trip works. The worker should clear its warning state on the next scheduled heartbeat. If the banner persists for more than a few minutes after this, restart the worker process.
  • A response with "ok": false will include a reason. The two common ones are "reason": "invalid_token" (rotate the token in your dashboard and update ~/.commander/license.token) and "reason": "revoked" (check Billing in the dashboard).
  • A network error or hang means the VPS cannot reach runcommander.com over HTTPS at all. Test with curl -v https://runcommander.com/api/health to see whether the failure is DNS, TCP, or TLS, and check your egress rules.

When to contact support

Reach out to hello@dekimu.com if any of the following are true:

  • The manual curl above returns "ok": true but the dashboard banner does not clear within 10 minutes.
  • Your Billing status is current and the license server still responds with "reason": "revoked".
  • You see a state value that is not one of OK, WARN_1, WARN_2, HALTED, or REVOKED.
  • The worker logs show heartbeats succeeding but in-flight runs are being killed (this should never happen — Commander always drains).

Include the output of the manual curl test and the last 50 lines of your worker log in your first message. That is usually enough for us to identify the cause without a back-and-forth.