Troubleshooting
Diagnose common startup and configuration failures on a self-hosted stack.
Most problems show up at startup. Start with the service state and the API logs:
cd ~/sdp
docker compose ps
docker compose logs -f sdp-apiDocker is not ready
The install script checks Docker first. If it reports that Docker isn't installed, that Compose v2 is unavailable, or that the daemon isn't reachable, install or start Docker and retry. See the Docker Engine and Compose install guides.
A required variable is missing
compose.yml stops with a message such as set POSTGRES_PASSWORD in .env when a required variable is unset. Make sure .env sits next to compose.yml and sets every required variable. The configurator writes a complete file, and the environment reference lists what's required.
Images won't pull
If docker compose pull reports access denied or a missing manifest:
- Check that
SDP_IMAGE_REGISTRYandSDP_VERSIONname a registry and tag you can reach. Release tags look likevX.Y.Z. - Pull one image directly to see the underlying error, for example
docker pull ghcr.io/solana-foundation/sdp/sdp-api:latest. - If the registry is private, run
docker loginfor it first.
Port already in use
The API, dashboard, and docs use ports 8787, 3000, and 3001 by default. If another process holds one, that service can't bind. Set SDP_API_PORT, SDP_WEB_PORT, or SDP_DOCS_PORT in .env, update the browser-facing URLs that name that port (the NEXT_PUBLIC_* URLs, and FRONTEND_URL for the dashboard), and run docker compose up -d again.
Migrations failed
sdp-migrate runs before the API starts. If it fails, the API stays down. Read its logs:
docker compose logs sdp-migrateA failure here is usually a database connection problem. Check POSTGRES_* (or DATABASE_URL), and that postgres shows as healthy in docker compose ps.
Database connection refused
The API and migrations wait for Postgres to report healthy before they start. If they still can't connect, check the credentials in .env. With an external database (DATABASE_URL set), check that it's reachable from inside the Docker network.
Dashboard sign-in fails
Most sign-in failures are Clerk configuration. Check NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, and CLERK_ISSUER against your Clerk application, and that the keys belong to the instance (development or production) you mean to use. Then look for these messages:
Clerk token missing organizationorClerk token has no usable email claim, in the failing request's401response: the session token lacks the claims in the Clerk setup guide.Clerk session refused: not issued to the dashboard, in the API logs:FRONTEND_URLisn't the origin the dashboard loads from. WithENVIRONMENT=production, the API accepts only sessions issued to that origin.
The local signer isn't offered
If the local provider is missing from the dashboard, CUSTODY_PRIVATE_KEY isn't set. If choosing it returns Local requires manual activation for this organization., add the organization override from First devnet deployment, and check that the Clerk webhook reaches the API.
Still stuck?
Collect the failing service's logs and your .env settings with the secrets removed, then open an issue on the project repository.