Troubleshooting¶
Symptoms first, then the cause and the fix. Start every investigation with:
curl -s http://<core>/v1/install/status
docker logs axium-core 2>&1 | grep -E '^\[(install|db|license|observability|errorHandler)\]'
Startup¶
The container exits immediately with an environment error
envalid prints the offending variable. Typical cases:
MASTER_ENCRYPTION_KEY: must be 64 hex characters (32 bytes): a trailing newline, a key of the wrong length, or a Base64 value. Generate withopenssl rand -hex 32 | tr -d '\n'.DATABASE_URL: ... missing: not passed at all.AXIUM_METASERVERorPORTinvalid.
[db] waiting for postgres... for 30 seconds, then the process dies
The core cannot open a connection. Check, in order: the host in
DATABASE_URL resolves from inside the container (axium-db on the same
Docker network, not localhost), the port, the credentials, and that
PostgreSQL accepts the connection (pg_hba.conf, Cloud SQL attachment,
sslmode). A Cloud SQL DSN needs the @localhost/db?host=/cloudsql/…
form.
/v1/install/status returns not_installed after startup
The automatic install failed. grep '\[install\]' in the logs. The usual
message is permission denied for database: the user cannot create
schemas.
Then restart the core, or call POST /v1/install.
/v1/install/status returns partial
Axium schemas exist without the core.schema_version table: an
installation died halfway, or someone restored a partial dump. On a fresh
installation, drop the schemas and restart:
On a database with data, do not drop anything; contact support with the logs.
The database is at schema version N but this build ships M
You started an older image against a database that a newer version had already migrated. Deploy the newer image. Schema never downgrades.
[install] migration failed
The process exits on purpose. Restore the backup taken before the upgrade, roll the image back, and send the log line to support.
[observability] disabled: …
The destination could not be set up. Causes: unreadable DSN, the trace
database user lacks CREATE, a telemetry schema left half-created
(partial), an unparseable OBSERVABILITY_HTTP_HEADERS. Fix the value
and restart; observability does not retry during the process's life.
Console¶
The login page shows a network error
The browser cannot reach API_URL. Open the browser's developer tools:
- Mixed content blocked: the ui is
https://andAPI_URLishttp://. Usehttps://. - Name not resolved:
API_URLuses an internal name (http://axium-core:3000/v1). It must be a URL the browser can reach. - CORS error: usually a proxy in front of the core stripping headers
or answering the pre-flight itself. The core allows all origins; let
OPTIONSrequests through. - 404 on login:
API_URLis missing the/v1suffix or has a trailing slash.
Invalid email or password with the initial credentials
The user was already changed, or the database was restored from another
installation. Reset with an administrator account, or, if none is
available, with SQL against core.users (ask support for the procedure).
Providers fail after a restore or a redeploy
MASTER_ENCRYPTION_KEY differs from the one the credentials were
encrypted with. Recover the original key. If it is gone, edit each
provider and enter its credentials again.
Runtime (SDK traffic)¶
401 from the gateway
The key is unknown, inactive or expired; all three answer the same. Check
the key in the console (GET /v1/rm/api-keys), its expires_at, and
that the SDK actually sends it: the OpenAI SDK as Authorization: Bearer,
Google's as x-goog-api-key. A ?key= query parameter is ignored.
403 from the gateway
Read the error message and the trace's denial_reason:
| Message / reason | Fix |
|---|---|
| key of another app, scope mismatch | Use a key created for this proxy app. |
app_not_ready |
Publish the app (PATCH /v1/proxy-apps/:id/publish) or reactivate it. |
model_not_allowed |
Add the model to the app's allow-list, or fix the name. |
provider_inactive |
Activate the provider. |
firewall_denied |
Client IP not allowed. Behind a proxy, set TRUST_PROXY=true or every client looks like the proxy. |
dlp_blocked |
The prompt contained data the policy blocks. |
404 Route not found from the Vertex gateway in Java
The SDK entered Vertex express mode because it was given .apiKey()
alone and changed the path to /v1/publishers/…. Pass the key as a
static credential instead; see SDK examples.
429 from the gateway
Either the provider's own rate limit relayed verbatim (error_origin:
provider) or the app's budget (denial_reason: budget_exhausted).
Raise budget_limit, wait for the period to roll over, or check the
provider's quota.
Streaming arrives all at once at the end
Something in front buffers the response. Disable proxy buffering (nginx
proxy_buffering off, Caddy flush_interval -1). The core already sends
X-Accel-Buffering: no.
Uploads fail with 413 or a connection reset
Three limits apply: the reverse proxy's body size, MAX_UPLOAD_SIZE
(default 50 MB), and the container's memory, since uploads are buffered
in RAM. Align all three.
Gemini resumable upload: the second request goes to the wrong host
Set PUBLIC_BASE_URL=https://axium-api.your-domain.com and
TRUST_PROXY=true so the upload URL handed back points through Axium
with the right scheme.
403 PERMISSION_DENIED … aiplatform.endpoints.predict on Google Cloud
The core's service account lacks roles/aiplatform.user in the project
configured on the provider. Re-run gcp.sh or update.sh with
VERTEX_PROJECT=<that project>, or grant the role by hand.
Cost is null in traces and statistics
The model has no prices configured. Set input and output price per million tokens on the model.
Collecting information for support¶
curl -s http://<core>/v1/diagnostics -H "Authorization: Bearer <token>"
docker logs --since 1h axium-core 2>&1 | grep -vE '^\[(req|runtime|usage)\]'
Plus the x-axium-trace-id of a failing request, which identifies its trace.