Documentation

Troubleshooting

What the common failures look like, and what to do about each one.

Work down the chain: is the agent running, did it park on a relay, does the dashboard know where, can the app dial it.

systemctl status kino-agent                  # is it running?
journalctl -u kino-agent -n 50 --no-pager    # what does it think?

Installing an agent#

set: Illegal option -o pipefail#

You are on Debian or Ubuntu, where /bin/sh is dash, and an older copy of the installer ran a bash script with sh. Fixed — and the installer is fetched fresh each time, so re-running the same command picks up the fix. No new release needed.

error: registration failed - enroll key already used, or machine removed#

Install links are one-time. Either the install already succeeded once, or the machine was deleted from Machines. Delete the machine and add it again to get a fresh link.

error: bash is required to run the installer#

A minimal image with no bash. Install bash, or download the release binary and register the service by hand — see kino-agent.

must run as root - pipe through sudo#

The installer registers a system service. Re-run it with | sudo sh.

The machine never goes Live#

Presence is reported by the agent, so work backwards from it.

journalctl -u kino-agent -n 50 --no-pager
What you see What it means
Nothing; service not running sudo systemctl start kino-agent, then read the log again.
401 on refresh The machine was deleted here, or the credential is stale. Remove it from Machines, uninstall, and install again.
Connection refused or timeout The machine cannot reach a relay. Check it has outbound HTTPS — see below.
Parked, but still Dark here The agent connected but its report did not land. It re-reports on the next reconnect; give it a few minutes.

A machine shows as Dark after 36 hours with no report. That window is deliberately generous, so “Dark” on a box you rebooted five minutes ago means the agent genuinely is not talking.

Outbound connectivity#

The agent needs to reach two things and nothing else. From the machine:

curl -fsS https://kino.dpdns.org/healthz    # -> ok

If that fails, the machine has no route out, or something is filtering it. No inbound port is ever needed, and no firewall rule has to be added for Kino.

invalid peer certificate: UnknownIssuer#

Something on the network is intercepting TLS and re-signing it with its own certificate authority — a corporate firewall doing deep inspection. Your laptop elsewhere works fine, which is what makes this confusing. Confirm it:

openssl s_client -connect <host>:443 -servername <host> </dev/null 2>/dev/null \
  | openssl x509 -noout -issuer

If the issuer is your company’s firewall rather than a public certificate authority, ask whoever runs it to exempt the hostname from SSL inspection. That is the clean fix — the machine then sees the real certificate and nothing else has to change.

Failing that, the machine can be told to trust the firewall’s CA: drop it in /usr/local/share/ca-certificates/ and run update-ca-certificates.

Take the CA, not the leaf

openssl s_client prints the whole chain, and the first certificate in it is the server’s own — installing that fixes nothing. You want the issuer.

Connecting#

no presence reported for this agent yet#

The agent has never successfully parked on a relay. Same checks as above — this is the machine’s problem, not the app’s.

The connection opens, then SSH fails immediately#

You reached the machine. Everything from here is ordinary SSH.

  • Is sshd running, on port 22? The agent forwards to 127.0.0.1:22 and nowhere else.
  • On Windows, is OpenSSH Server installed? It is not there by default, and this is the single most common cause.
  • Wrong username or credential? The target’s own sshd is authenticating you, exactly as it would over a direct connection.

The host key changed#

Kino SSH Manager pins each machine’s SSH fingerprint. A warning means the fingerprint moved — because you rebuilt the machine, or because something is impersonating it.

Reinstalling the OS while keeping the same machine entry is exactly the case the pin exists to catch. Clear it deliberately, once you know why it changed. Do not click through it.

Sessions drop after about a minute of inactivity#

If you are on a relay you run yourself, this is a proxy timeout — see below. On Kino Cloud relays it should not happen; tell us if it does.

Running your own relay#

Only relevant if you followed Self-hosting.

Every connection fails with 400 Bad Request#

Missing WebSocket upgrade headers. A default proxy_pass does not forward them:

map $http_upgrade $connection_upgrade { default upgrade; '' close; }

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

Use $connection_upgrade from the map rather than a literal Connection "upgrade" — the literal breaks ordinary requests like the health check.

Idle sessions get cut#

Timeouts. proxy_read_timeout defaults to 60 seconds in a location, and proxy_timeout to 10 minutes in a stream block. The relay pings its control channel, but a data socket has no keepalive, so an idle terminal is dropped. Set both to 1h.

could not reach https://…/healthz - is the relay up and public?#

Enrollment is refused until the relay answers publicly. Test from a machine that is not the relay:

curl -fsS https://relay.example.com/healthz

Usual causes: DNS not propagated yet, the TLS certificate not issued, nginx not reloaded, or RELAY_PUBLIC_URL not matching the real hostname.

The wrong certificate is served#

The relay’s server block is not matching, so another one answers. Check that the address it listens on is the address your proxy actually connects to — listen 8443 binds 0.0.0.0:8443, which is a different socket from 127.0.0.1:8443.

ss -ltnp | grep 8443

The relay started without authentication#

It says so at startup. A relay with neither RELAY_TOKEN nor an enrolled public key accepts anyone who can reach it and knows an agent id. Set RELAY_TOKEN, or complete enrollment, and restart.

Still stuck#

Collect these first — they answer most questions on sight:

journalctl -u kino-agent -n 100 --no-pager
curl -sS -o /dev/null -w '%{http_code}\n' https://kino.dpdns.org/healthz

Include the machine name and roughly when it last worked.