Skip to content

First-Run Troubleshooting

Use this page when a Get Started step fails. Every request you make crosses the same boundaries in the same order, so diagnose in that order and stop at the first boundary that fails - do not change policy, credentials, and routing at the same time:

flowchart LR
  Ready[Stack readiness] --> SignIn[Console sign-in] --> Identity[Application identity] --> STS[Token service] --> GW[Gateway] --> Up[Upstream service] --> Audit[Audit trail]

Run the failing step once and keep its request ID or exact error, then start at the matching section below. For production incidents and deeper operational diagnosis, use Troubleshoot by Symptom.

The same command works in every shell:

Terminal window
caracal status --ready --json
SymptomCheck
Docker command failsConfirm Docker Desktop or Docker Engine is running and docker compose version succeeds.
A service is not readyWait for the dependency named in the JSON output, then rerun readiness.
Ports are already in useStop the local process holding the port; the local port map is in Defaults and Limits.
Stack state looks staleRun caracal down, then caracal up. Use caracal purge only when you intentionally want to remove local state.
SymptomCheck
Sign-up is rejected or the access-denied page appearsThe packaged console closes registration by default and shows one uniform page for every allowlist denial. On the runtime host, run caracal allowlist list to inspect entries, then caracal allowlist add <email> or caracal allowlist unlock <email> - see Control Console Access. Make sure a sign-in method is configured in $CARACAL_HOME/caracal.env - see Enable Console Sign-In.
Google or GitHub buttons are missingSet both the client ID and client secret for the provider, then rerun caracal up.
The provider rejects sign-in with a redirect URI mismatch (Google shows Error 400: redirect_uri_mismatch)The OAuth client does not list the console’s callback URL. The packaged console signs in through http://localhost:3001/api/auth/callback/google (or .../github); a source-checkout caracal web session uses port 3002 instead, and a custom CARACAL_WEB_URL moves the origin with it. Add the packaged callback to the OAuth client - Google accepts several redirect URIs, while a GitHub OAuth app takes one callback URL per app - then retry; no stack restart is needed.
Password sign-in is blocked pending verificationThe packaged console requires a verified email. Confirm CARACAL_SMTP_URL and CARACAL_SMTP_FROM are set and the verification message was delivered.
SymptomCheck
Caracal.fromEnv: provide CARACAL_APP_CLIENT_SECRET or a similar constructor errorExport CARACAL_ZONE_ID, CARACAL_APPLICATION_ID, and CARACAL_APP_CLIENT_SECRET exactly as in Give the Agent Its Identity, or set CARACAL_CONFIG to a complete profile.
SDK cannot load configurationCARACAL_CONFIG must name an existing profile file; a missing file at that path is an error, not a fallthrough.
Authentication is rejected (401)The client secret no longer matches the application - reveal the current value from the application’s detail panel, or rotate it and update your environment or secret file.
Secret file is rejectedEnsure the file named by app_client_secret_file exists and is readable only by the current user.

The application client secret is held sealed server-side. If you lose your local copy, reveal it again from the application’s detail panel in the web console - each reveal is recorded in the zone audit timeline - or rotate the secret and update your environment or secret file with the new value.

The STS is Caracal’s token service: it checks policy and issues mandates. A 403 from it means your program authenticated successfully but policy did not allow what it asked for.

CheckFix
Active policy setActivate the starter policy set created by guided setup.
Resource IDUse the resource ID you created in guided setup.
ScopesRequest only scopes covered by the starter policy.
Audit request IDOpen web console Audit with the request ID to see the policy diagnostic.

A Gateway 403 means policy already said yes and a mandate was issued, but the Gateway rejected the request before forwarding it upstream.

CheckFix
Authorization headerThe SDK transport attaches Authorization: Bearer <mandate>; send requests through it rather than a plain HTTP client.
Resource headerThe SDK sets X-Caracal-Resource from the resource ID you pass; confirm it matches guided setup.
Mandate freshnessMandates are short-lived and single-use by design; rerun the example to mint a fresh one.
RevocationConfirm the session, application, or delegation was not revoked.
Route bindingConfirm the resource has the Gateway route and upstream URL you intended.
SymptomCheck
Connection refusedThe upstream service is not listening, or the Gateway cannot reach that host and port.
DNS failureUse a hostname visible from the Gateway container, not only from the host shell.
Demo upstream missingConfirm the resource’s upstream URL is reachable from the Gateway container and the provider key sealed on the provider is current.
Wrong pathUse a known-good path on the upstream before trying custom paths.
CheckFix
Wrong request IDCopy the request ID from the STS, Gateway, SDK, or web console output.
Wrong zoneSelect the zone used by guided setup.
Request never reached STS or GatewayConfirm the example used your configuration and the Gateway URL it derives.
Audit ingestion lagWait briefly and refresh the web console audit view.

Repeat only the failed step. Success means readiness passes, the protected call returns the upstream response, and Audit contains both the authorization decision and the Gateway result under the same request trace.

After the first run succeeds, continue with Tutorials or the language-specific SDK guides.