Keysat Docs
Operate · Day-to-day

Operate.

Backups, migration, recovery, and the things that go wrong. The "you didn’t expect to need this page until you needed it" page.

Backups

StartOS handles backups for you. By default, every service in your StartOS install is included in the same backup snapshot — you set the destination once (encrypted external drive, S3-compatible cloud, etc.) and StartOS schedules nightly snapshots.

The Keysat backup payload is intentionally tiny. It contains:

That’s it. No log files (those rotate locally), no caches.

Verify your backup destination at least once. Restoring on a fresh Start9 with a corrupted backup is exactly the wrong moment to discover that your destination wasn’t actually configured. StartOS → Settings → Backups → Test.

Your BTCPay store data and your Bitcoin wallet are separate backups, handled by the BTCPay and Bitcoin Core packages respectively. Keep them on the same backup destination so they restore in lockstep.

Migrating to new hardware

The full migration path:

  1. On the old Start9, ensure your most recent backup is complete and includes Keysat. Confirm the destination is writable and that snapshots have finished.
  2. On the new Start9, complete first-time setup with a fresh password. Don’t install any services yet.
  3. StartOS → Settings → Backups → Restore. Point at the same destination. Pick the most recent snapshot.
  4. StartOS restores all services in dependency order. Keysat will restore alongside BTCPay and Bitcoin Core. Bitcoin will need to re-sync if you’re using Bitcoin Core (consider utxo.live for assumeutxo to skip IBD).
  5. Once Keysat is running on the new box, your purchase URLs change — the LAN/Tor hostnames are different. Update any links you’ve published.

The signing keypair restores along with the database, so all previously-issued licenses verify identically against the same public key. You don’t need to re-distribute the public key to your customers.

Rotating the signing key

You generally don’t want to rotate the signing key — doing so invalidates every license you’ve ever issued. v0.1 doesn’t support rotation; the key is generated once at first start and never changed.

If you absolutely need to rotate (e.g. you suspect the keypair has leaked off the box):

  1. Stop Keysat.
  2. Move /data/issuer-key.pem aside.
  3. Restart Keysat — it will generate a fresh keypair on first run.
  4. Re-issue all active licenses to existing customers using the new key. The admin UI doesn’t support bulk re-issuance yet; this is a manual SQL exercise.
  5. Push a software update that swaps the embedded public key.

The cleaner path, for v0.2 onward, will be to support a rolling rotation where both keys verify for a transition period.

Troubleshooting

"Invalid BTCPay URL" when clicking Connect BTCPay

Keysat is selecting a BTCPay URL that isn’t reachable from your browser. This usually means the picked URL is a StartTunnel-local 10.59.x.x address rather than your LAN/mDNS one.

Fix: open BTCPay’s service page in a separate tab, copy the URL it shows under "Network — mDNS" or "Network — LAN", and confirm Keysat is using a similar shape. If you’re on Tor only, BTCPay needs to expose its admin UI over Tor too.

"Payment method unavailable" on first invoice creation

BTCPay rejects the invoice request because the store has no configured wallet. Open BTCPay, find your store, and configure either an on-chain wallet or a Lightning node before retrying.

Webhook deliveries failing

Check the audit log in the admin UI — failed deliveries land there with the response status. Common causes:

"database is locked" errors in logs

Almost always a sign that two daemon instances are racing on the same SQLite file — usually because of a misconfigured supervisor. Confirm only one Keysat container is running. If you’re seeing this on a fresh install with no customizations, file a bug report against the package version you’re running.

Licenses verifying as "expired" immediately after issue

Clock skew. Either the issuing host or the verifying host has the wrong time. Run NTP. StartOS keeps your Start9 in sync automatically; the issue is usually on the verifier side (e.g. an air-gapped buyer machine).

Reading the logs

Keysat logs to stdout, captured by StartOS. Tail them from the StartOS dashboard — Service page → Logs → Live tail.

Useful log lines to grep for:

PatternWhat it means
license issuedSuccessful license issuance. Includes license id and product.
btcpay webhook receivedBTCPay delivered an event. Followed by a "settled" or "expired" disposition line.
auth failedBad admin API key on a request to /v1/admin/*.
signature mismatchBTCPay webhook arrived with the wrong HMAC. Either misconfigured or actively malicious.
migration appliedA schema migration ran on startup. Normal during package updates.

Getting help

If you’re stuck: