Troubleshooting
This page is a symptom-driven checklist for the current server (./sbt "server/run").
Server won’t start
“Missing env 'PG_JDBC_URL' / 'PG_USERNAME' / 'PG_PASSWORD'”
Cause: GRAVITON_BLOB_BACKEND is set to s3 or minio, which uses PostgreSQL manifests.
Fix: supply the PostgreSQL settings for that deployment, or set GRAVITON_BLOB_BACKEND=fs for the self-contained filesystem server.
“Unsupported GRAVITON_BLOB_BACKEND='…'”
Cause: GRAVITON_BLOB_BACKEND must be one of fs, s3, or minio.
Fix:
export GRAVITON_BLOB_BACKEND="fs"“Missing env var 'GRAVITON_S3_ENDPOINT' / 'GRAVITON_S3_ACCESS_KEY' / 'GRAVITON_S3_SECRET_KEY'”
Cause: you selected GRAVITON_BLOB_BACKEND=s3|minio but didn’t provide S3 endpoint credentials.
Fix: either set the MinIO env vars, or switch to filesystem blocks.
export GRAVITON_BLOB_BACKEND="fs"/api/health works, but uploads fail
Upload returns 500 and mentions Postgres tables / relations
Cause: Postgres is reachable, but the schema wasn’t applied.
Fix:
PGPASSWORD=postgres \
GRAVITON_DATABASE_URL=postgresql://postgres@localhost:5432/graviton \
./scripts/migrate-postgres.shUpload returns 500 on MinIO/S3 mode
Common causes:
- The bucket
GRAVITON_S3_BLOCK_BUCKETdoes not exist. - Your MinIO credentials are wrong.
Fix (bucket creation with Docker mc):
docker run --rm --network host minio/mc \
alias set local "$GRAVITON_S3_ENDPOINT" "$GRAVITON_S3_ACCESS_KEY" "$GRAVITON_S3_SECRET_KEY"
docker run --rm --network host minio/mc \
mb local/"$GRAVITON_S3_BLOCK_BUCKET"Upload returns 500 “Empty blobs are not supported…”
Cause: the ingest pipeline rejects empty bodies (size must be > 0).
Fix: ensure your client is actually sending bytes (for curl, use --data-binary @file and confirm the file is non-empty).
Downloads fail
GET /api/v1/blobs/:id returns 400
Cause: the blob id could not be parsed.
Blob IDs must be:
<algo>:<digestHex>:<byteLength>
Example:
blake3:7b1d...:12
Download returns 404
The content ID is valid, but its manifest is not present in the configured repository. This is expected after DELETE, which removes the logical manifest while retaining shared blocks.
If you suspect a config issue, validate:
- Postgres is reachable and has the schema applied
- Your selected block backend is pointing at the correct data (filesystem root/prefix or MinIO bucket/prefix)
Metrics endpoint issues
/metrics returns 404
Cause: you’re not hitting the current server (or something is proxying away that route).
The current server mounts metrics at:
GET /metrics
Operations console can’t reach your server
The console defaults to http://localhost:8081. You can set the endpoint with the connection bar or an api query parameter:
http://localhost:5173/demo?api=http://localhost:18081If the API is running on another origin, use the default security-disabled local mode or add the console's exact origin to GRAVITON_SECURITY_CORS_ALLOWED_ORIGINS. Security-enabled canonical blob routes validate browser preflights before the console sends its bearer token. A same-origin reverse proxy is also supported. The console reports request failures directly and does not load substitute data.
Still stuck?
- Re-run the complete local recipe in Run Locally (Full Stack).
- Check the exact env vars the server sees:
env | sort | grep -E '^(PG_|GRAVITON_|MINIO_)'.