> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cymph.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Common issues

> Diagnose a self-hosted Cymph deployment that will not start or is not reachable.

Run every command below from the directory containing `compose.yaml`.

## Start here: service status

```bash theme={"system"}
sudo docker compose ps
```

Each of `db`, `api` and `ui` reports a health state, and Compose starts them in order — `db`, then `api`, then `ui`, then `nginx`. A service stuck in `starting` or marked `unhealthy` blocks everything after it, so work on the **earliest** unhealthy service first. A later service that never started is usually a symptom, not the cause.

For the logs of a single service:

```bash theme={"system"}
sudo docker compose logs api
sudo docker compose logs -f nginx   # follow
```

## nginx exits immediately on startup

The certificate and key are bind-mounted from host paths recorded in `.env`. If either path does not exist or is not readable, nginx fails at startup rather than serving without TLS.

Check the paths Compose is using, then confirm both files exist on the host:

```bash theme={"system"}
grep SSL_CERTIFICATE .env
ls -l /etc/ssl/bundle.crt /etc/ssl/cert.key   # substitute your own paths
```

If a path is wrong, correct it in `.env` and recreate the container so the new bind mount applies — a plain restart keeps the old mount:

```bash theme={"system"}
sudo docker compose up -d --force-recreate nginx
```

See [TLS certificates](/deployment/self-hosted/tls-certificates) for the file format and renewal.

## Port already in use

nginx is the only service that publishes a host port, on the address and port you chose during setup (`BIND_ADDRESS` and `BIND_PORT` in `.env`, default `0.0.0.0:443`). If something else on the host already holds that port, the container cannot bind and Compose reports an allocation failure.

Find the conflict:

```bash theme={"system"}
sudo ss -tlnp | grep :443   # substitute your BIND_PORT
```

Either stop the conflicting service, or change `BIND_PORT` in `.env` and recreate nginx. Note that binding below port 1024 requires the Docker daemon to run as root, which is why the install steps use `sudo`.

## The database never becomes healthy

```bash theme={"system"}
sudo docker compose logs db
```

Two causes account for most of it:

* **Missing or empty `db/secrets.txt`.** It is passed in as a Compose secret and holds the key generated by `env.sh`. If setup was interrupted, the file may be absent.
* **Permissions on the data directory**, which typically follows a restore where ownership was not preserved. See [Backup & restore](/deployment/self-hosted/backup-restore).

## The API never becomes healthy

The API healthcheck calls `/api/v1/misc/ping` inside the container. Reproduce it directly to separate an API problem from a proxy problem:

```bash theme={"system"}
sudo docker compose exec api wget -qO- http://127.0.0.1:5050/api/v1/misc/ping
```

If that responds but the browser does not, the problem is in nginx or the network path, not the API. If it does not respond, read the API logs — it fails to start when it cannot reach the database or when required values are missing from `.env`.

## The page loads but every request fails

This is the signature of a URL mismatch. `env.sh` writes the address you gave it into several variables (`CYMPH_APP_BASE_URL`, `NEXTAUTH_URL`, `NEXT_PUBLIC_WEBAPP_URL`, `CYMPH_BACKEND_API_ENDPOINT`, `NEXT_PUBLIC_BACKEND_API_ENDPOINT`) and into the nginx `server_name`. If you later change the hostname, port or scheme of the deployment, all of them have to agree — the browser is told to call an API address that no longer answers.

```bash theme={"system"}
grep -E 'URL|ENDPOINT|BIND_' .env
grep server_name nginx/nginx.conf
```

After correcting them, recreate the affected services:

```bash theme={"system"}
sudo docker compose up -d --force-recreate ui api nginx
```

## Cannot reach the deployment at all

Work outward from the host:

1. **On the host**, confirm the port is listening: `sudo ss -tlnp | grep :443`
2. **From the host**, confirm TLS answers: `openssl s_client -connect localhost:443 </dev/null`
3. **From a client**, confirm the host firewall and any network firewall permit the port.

If `BIND_ADDRESS` is set to `127.0.0.1` rather than `0.0.0.0`, the deployment is only reachable from the host itself.

## Certificate warnings in the browser

Expected with a self-signed certificate. With a CA-issued certificate it usually means the bundle is incomplete — the server certificate is present but the intermediates are missing, so clients cannot build a chain. Concatenate the full chain into the bundle file and restart nginx.

## Integrations fail with 403 or a timeout

The deployment is reaching your endpoint from an address that endpoint does not permit, or not reaching it at all. See [Networking](/deployment/networking).

## Features are missing or user creation is blocked

The license controls the global user limit and which features are enabled. Check the uploaded license and its expiry — see [Licensing](/deployment/self-hosted/licensing).

## Locked out of the administrator account

See [Resetting the administrator password](/deployment/self-hosted/reset-admin-password).

## Collecting information for support

If you need to raise an issue with Cymph, include the service states and recent logs:

```bash theme={"system"}
sudo docker compose ps > support.txt
sudo docker compose logs --tail 200 >> support.txt
```

<Warning>
  Review `support.txt` before sending it. Logs can contain hostnames, e-mail addresses and integration endpoints from your environment.
</Warning>
