Skip to content

Troubleshooting

Start with the table: find the status and message you got. If the message is too vague, follow the request id into the engine's log, which names the cause.

What you seeCauseFix
401 authentication requiredNo credential, or the token expired. A token lasts 15 minutes by defaultSign in again, or trade your refresh_token at POST /api/admin/auth/refresh
401 session invalidatedThe account's password was set again, its sessions were ended, or it was deletedSign in again
401 Invalid email or password. with the right passwordFive failed sign-ins within 15 minutes locked the account. A lock answers exactly like a wrong password, and the log says login refused: account is locked outWait for the 15 minutes to pass
401 API keys with an admin role are not accepted on the admin API. Use an admin token.An API key holding admin or super_admin called the Admin APIUse an admin token
401 Admin tokens are accepted on the admin API only.An admin token called the Content API or a public routeUse an API key or a session token there
401 invalid metrics tokenMETRICS_TOKEN is set, and the bearer token sent to /api/admin/metrics is not it. This includes a super admin's own session tokenSend METRICS_TOKEN
401 on POST /api/admin/setupThe setup token is wrong, or setup already finished and the token was retiredUse the token from the engine's log or LYEVE_SETUP_TOKEN. If an account exists, sign in instead
409 The initial setup has already been completed.The first administrator already existsSign in
403 insufficient scopeThe API key's scopes do not cover this method and pathGive the key the scope, such as content:write. See API keys
403 insufficient permissionsYour role cannot call this routeAsk a super_admin for the role. See roles
403 request carries no tenant scopeThe account or key belongs to no tenantGive the account a tenant membership
403 This route needs a signed-in session.An admin token or an API key called a route only a signed-in person may callCall it from a session
403 This token is not granted <grant>.The admin token's grants do not open this routeCreate a token with that grant
404 The requested endpoint does not exist.A wrong path or port, or a feature that is not runningCheck the port (3001 for /api/admin, 3002 for /api/v1), then GET /api/admin/plugins/status
404 tenant not foundX-Tenant-ID names a slug that does not existCheck the slug under Tenants
402 payment_requiredA paid part of a feature. feature in the body names itSee Licensing and tiers
402 cap_exceededA free tier limit. cap, limit and current say whichA license lifts it
405 schema is read-only over this transportThe content type's transports block does not allow this directionSee transports
409A slug or unique value is already takenPick another value
422A required field is missing, a value has the wrong type, or a rule failedThe body names the field
429 rate limit exceededToo many requests from your addressWait for the seconds in Retry-After
503 with the code SETUP_REQUIREDThe engine runs in setup modeFinish setup. See Installation
503 another instance is applying DDL for this schema; retry in 1sAnother replica is changing the same content typeRetry after the second in Retry-After
503 {"status":"starting", ...}The engine has not finished startingRetry after the seconds in Retry-After
503 with the code DATABASE_ERRORThe database is unreachableCheck the database and GET /api/admin/pool/health
An entry is missing from a listIt belongs to another tenant, it is a draft, or it was soft deletedA list holds published entries unless you name filters[_status]. Check tenant_id in the log line
The engine refuses to startA required setting is missing or a production check failedThe start error names every problem. See Installation

Errors answer JSON. error is written for a person, and most answers also carry a code to branch on in code:

{"error": "The requested endpoint does not exist.", "code": "not_found", "request_id": "0af7651916cd43dd8448eb211c80319c"}

The message never carries database or driver text. When it is too vague, the log line with the same request id has the cause.

Every response carries an X-Request-ID header. The engine takes it from the X-Request-ID you sent, when that is printable ASCII of 128 characters or less. Otherwise it uses the trace id of a W3C traceparent header, or makes a new one. Send your own to trace one call:

Terminal window
curl -i -H "X-Request-ID: debug-run-42" \
-H "Authorization: Bearer $TOKEN" \
http://localhost:3002/api/v1/content/article

The response carries X-Request-ID: debug-run-42, and every log line the request wrote carries "request_id": "debug-run-42". The quickstart shows how to get TOKEN.

The engine writes JSON lines to standard output. A line from a request carries level (DEBUG, INFO, WARN or ERROR), msg, request_id, tenant_id, plugin (the feature that wrote it) and, with tracing on, trace_id and span_id. The default level is INFO.

A few start-up lines are plain text, so have jq skip what does not parse:

Terminal window
# warnings and errors as they happen
docker logs -f lyeve-engine 2>&1 | jq -cR 'fromjson? | select(.level == "WARN" or .level == "ERROR")'
# everything one request wrote
docker logs lyeve-engine 2>&1 | jq -cR 'fromjson? | select(.request_id == "debug-run-42")'
# everything one tenant did
docker logs lyeve-engine 2>&1 | jq -cR 'fromjson? | select(.tenant_id == "acme")'

Logs, free on every install, adds search, live tail, export and log levels you change without a restart.

SymptomLook at
A feature is not thereGET /api/admin/plugins/status. A feature that is off carries a reason, such as not granted by the capability set
A paid feature stoppedGET /api/admin/entitlements: state and license_error
A route is slowGET /api/admin/debug/latency, then Request profiling
Memory or goroutines keep growingGET /api/admin/debug/goroutines, then the heap and goroutine profiles in Request profiling
Database calls time outGET /api/admin/pool/health
The instance is up but sends no traffic/readyz, as API endpoints lists under health