Troubleshooting
Common issues and how to resolve them
Address already in use
listen tcp :3488: bind: address already in useAnother process is already using the port.
Check whether CH-UI is already running:
ch-ui server statusThen stop the old process:
ch-ui server stopIf status says the PID file is missing but the port is in use, you likely upgraded from an older binary without PID management. Stop the old process once, then restart with the current build.
Connector auth failures (invalid token)
- Verify you copied the latest
cht_...token. - Check active connections with
ch-ui tunnel list. - Regenerate with
ch-ui tunnel rotate <connection-id>(or create a new one withch-ui tunnel create --name ...). - Confirm the agent uses the correct
--urland token pair.
Login fails
CH-UI surfaces explicit login states (invalid credentials, offline connection, retry window). If login fails:
- Verify the selected connection is online.
- Confirm ClickHouse credentials are correct for that connection.
- Check connector logs for upstream errors.
Rate-limit lockouts are progressive and capped:
- 1st lock:
3 minutes - 2nd lock:
5 minutes - 3rd+ lock:
10 minutes(cap)
Can't login? (local recovery)
If local URL/connection setup is wrong, restart CH-UI with explicit values:
ch-ui server --clickhouse-url http://127.0.0.1:8123 --connection-name "My Connection 1"Environment-variable equivalent:
CLICKHOUSE_URL=http://127.0.0.1:8123 CONNECTION_NAME="My Connection 1" ch-ui serverDocker:
docker run --rm -p 3488:3488 -v ch-ui-data:/app/data \
-e CLICKHOUSE_URL='http://127.0.0.1:8123' \
-e CONNECTION_NAME='My Connection 1' \
ghcr.io/caioricciuti/ch-ui:latestFull guide: Can't Login?
WebSocket / tunnel fails behind proxy
Your reverse proxy must forward WebSocket upgrades on /connect:
- Pass
UpgradeandConnection: upgradeheaders. - Set long read/send timeouts (e.g.
proxy_read_timeout 3600). - Disable buffering for the tunnel path.
Example Nginx config for the /connect path:
location /connect {
proxy_pass http://127.0.0.1:3488/connect;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600;
}Health check
Use the health endpoint to verify the server is running:
curl http://localhost:3488/healthDashboards flicker / query history vanishes / SESSION_IS_LOCKED
You're running ClickHouse as multiple pods behind a load balancer. system.* tables are node-local, so without sticky routing every refresh hits a different pod. See ClickHouse Clusters & Load Balancers for the X-CH-UI-Session header config — and crucially, don't also enable ClickHouse's native session_id URL param, which serialises queries through a server-side mutex.