# Troubleshooting

> Diagnose common installation, login, TLS, enrollment, and upgrade failures.

URL: https://docs.serverbee.app/en/docs/troubleshooting

Start with the symptom below. Run commands on the affected host and avoid posting tokens, enrollment codes, API keys, or the first-run password in an issue.

## First checks [#first-checks]

```bash
sudo serverbee status
sudo ss -ltnp | grep -E ':(80|443|9527)[[:space:]]'
```

Then inspect the logs for your deployment:

| Deployment     | Command                                                  |
| -------------- | -------------------------------------------------------- |
| systemd Server | `sudo journalctl -u serverbee-server -n 100 --no-pager`  |
| systemd Agent  | `sudo journalctl -u serverbee-agent -n 100 --no-pager`   |
| OpenRC         | `sudo tail -n 100 /var/log/serverbee-{server,agent}.log` |
| Docker Server  | `docker logs --tail 100 serverbee-server`                |
| Docker Agent   | `docker logs --tail 100 serverbee-agent`                 |

## First-run password is missing [#first-run-password-is-missing]

The random password is printed once, only when the first user is created. Read the complete last credentials block:

```bash
sudo journalctl -u serverbee-server --no-pager \
  | grep -A8 'FIRST-RUN ADMIN CREDENTIALS' | tail -n 9

docker logs serverbee-server 2>&1 \
  | grep -A8 'FIRST-RUN ADMIN CREDENTIALS' | tail -n 9
```

If a user already exists, restarting does not generate another password. Use the supported account recovery/admin path for that installation; do not delete the database to force first-run behavior.

## Login loops or the cookie is not stored [#login-loops-or-the-cookie-is-not-stored]

Keep the public URL and cookie mode aligned:

* Plain `http://IP:9527` requires `auth.secure_cookie = false`.
* HTTPS requires `auth.secure_cookie = true`, and the proxy must forward `Host`, `X-Forwarded-Proto`, and WebSocket upgrades.

After changing `/opt/serverbee/etc/server.toml`, run `sudo serverbee restart server`. Clear only the ServerBee site's cookies and retry. Do not disable Secure cookies on an HTTPS production deployment.

## Port, DNS, or certificate setup fails [#port-dns-or-certificate-setup-fails]

* Direct-IP mode needs inbound TCP `9527`.
* Managed domain mode needs inbound TCP `80` and `443`, and no non-Caddy listener on either port. Keep `9527` private.
* Confirm the domain resolves to this host with `getent ahosts monitor.example.com`.
* Inspect Caddy with `sudo caddy validate --config /etc/caddy/Caddyfile` and `sudo journalctl -u caddy -n 100 --no-pager`.

Fix DNS/firewall/listener conflicts first, then rerun `sudo serverbee domain setup --domain monitor.example.com --email admin@example.com -y`.

## Agent stays offline or enrollment fails [#agent-stays-offline-or-enrollment-fails]

1. Confirm the Agent's `server_url` exactly matches the browser's reachable HTTP/HTTPS origin.
2. Check the Agent log for `expired`, `consumed`, `replaced`, rate-limit, TLS, or connection errors.
3. Enrollment offers are bound, single-use, and expire after 10 minutes by default. Replace the exact outstanding offer on the existing Server when necessary.
4. Before claim, correct values locally:

```bash
sudo serverbee config set server_url https://monitor.example.com -y
sudo serverbee config set enrollment_code NEW_ONE_TIME_CODE -y
```

Do not rerun `install agent` over a managed Agent. After a successful claim, use graceful or emergency re-enrollment from the Server detail page instead of changing the consumed code.

## The selected release channel is unexpected [#the-selected-release-channel-is-unexpected]

```bash
sudo serverbee status
sudo serverbee upgrade --channel stable -y
sudo serverbee upgrade --channel beta -y
```

The default `auto` policy prefers a suffix-free stable release and falls back to a prerelease only when no stable release exists. The installer saves `auto`, `stable`, or `beta` per component and reuses it for upgrades; either explicit command above replaces the saved policy after a successful upgrade. Selection follows the SemVer suffix rather than GitHub's potentially incorrect prerelease flag. For deterministic recovery, pass `--version vX.Y.Z` and verify that exact release's assets/checksums. After an upgrade, confirm the service/container is healthy, its restart count is stable, `/healthz` succeeds, and the UI/About version matches the intended release.

## Getting help [#getting-help]

Include the deployment method, OS/init system, expected and actual version, redacted config keys, the exact command, exit status, and relevant log lines. State whether `/healthz` works and whether the failure affects Server, Agent, browser, or reverse proxy. Never include credentials or tokens.

<Cards>
  <Card title="Quick Install" href="/en/docs/quick-start" />

  <Card title="Deployment" href="/en/docs/deployment" />

  <Card title="Configuration" href="/en/docs/configuration" />
</Cards>
