Troubleshooting

This guide covers the most common issues encountered when building, deploying, and running services on the Tawa platform. Start with tawa troubleshoot for AI-powered diagnostics, or use the sections below to diagnose specific problems.

Build Failures

Build fails immediately

Run tawa logs --build <id> to see what went wrong. Common causes:

  • Missing framework annotationcatalog-info.yaml must include insureco.io/framework. Without it, the builder cannot generate a Dockerfile or determine how to start your service.
  • Syntax errors in catalog-info.yaml — Invalid YAML will cause the catalog parse step to fail before any build work begins.
  • Wrong build command — If you've overridden insureco.io/build-command, verify it matches a script in your package.json.

Always run tawa validate (or tawa preflight) before deploying. It catches the most common configuration errors without burning a build attempt.

Docker build fails

  • Missing package.json — The builder expects a valid Node.js project at the build context root.
  • TypeScript errors — If npm run build exits non-zero due to type errors, the Docker build step fails. Fix type errors locally before pushing.
  • Wrong output directory — If your build outputs to a non-standard directory, set insureco.io/output-dir in your annotations.

Deploy Gate Blocked

If you see "Deploy gate: insufficient gas reserve", your wallet balance is below the three-month hosting reserve required for your pod tier.

Required reserve formula:

gas/hour × 24 hours × 30 days × 3 months

For example, a nano pod (5 gas/hour) requires 10,800 tokens in reserve.

Fix:

tawa wallet          # Check current balance
tawa wallet buy 15000   # Top up (example amount)

After purchasing tokens, retry your deploy.

Pod Crashes (CrashLoopBackOff)

A pod in CrashLoopBackOff is starting and immediately exiting. Diagnose with:

tawa logs       # What is the pod printing before it crashes?
tawa pods       # How many restarts has the pod accumulated?

Common causes:

  • Missing environment variable — Your app reads a required env var that was not injected. Check tawa config list to verify all expected vars are present. If a dependency URL is missing, make sure it is declared in internalDependencies in catalog-info.yaml.
  • Wrong start command — The default start command for your framework may not match your project. Override with insureco.io/start-command in annotations.
  • Port mismatch — If your app listens on a port other than 3000, set insureco.io/port in annotations.
  • Missing health endpoint — If the app crashes before the health endpoint becomes available, health checks fail immediately. See the Health Check section below.
  • Uncaught startup exception — A database connection error, missing config, or thrown exception at startup will cause the process to exit. Read the logs carefully.

OOMKilled

An OOMKilled pod is exceeding the memory limit for its pod tier. Upgrade the tier in catalog-info.yaml:

metadata:
  annotations:
    insureco.io/pod-tier: "small"   # was "nano"

Pod tier options and their memory limits:

TierMemory
nano256 Mi
small512 Mi
medium1 Gi
large2 Gi
xlarge4 Gi

After updating, commit, push, and redeploy.

Health Check Failing

The builder probes your health endpoint after deploy. If the endpoint does not return HTTP 200, the build is marked failed.

Expected endpoints by framework:

FrameworkHealth Endpoint
express, hono, fastifyGET /health
nextjsGET /api/health
worker(no health check)

Your health endpoint must return any 200 response. A minimal implementation:

// Express / Hono / Fastify
app.get('/health', (_req, res) => {
  res.json({ status: 'ok' })
})
// Next.js App Router: app/api/health/route.ts
export async function GET() {
  return Response.json({ status: 'ok' })
}

NOTE: Health checks use the same port as your service (default 3000). Ensure your app is listening on the correct port before handling requests.

Database Connection Refused

If your app cannot connect to MongoDB, Redis, or Neo4j:

  1. Check that the database is declaredMONGODB_URI, REDIS_URL, and NEO4J_URI are only injected if the corresponding database is declared in spec.databases:
spec:
  databases:
    - type: mongodb
  1. Verify the var is present — Run tawa config list after deploying and confirm the env var appears in the list.

  2. Check for typos in the type — Only mongodb, redis, and neo4j are supported. Using postgres, mysql, or anything else will fail during tawa preflight.

Dependency URL Not Injected

If a {SERVICE}_URL environment variable is undefined at runtime:

  • Confirm the dependency is declared in spec.internalDependencies in catalog-info.yaml.
  • After adding a dependency, you must redeploy for the env var to be injected.
  • Check tawa config list to verify the var appears after deploying.

Example: to get SEPTOR_URL injected, your catalog-info.yaml needs:

spec:
  internalDependencies:
    - service: septor

OAuth Errors

BIO_CLIENT_ID or BIO_CLIENT_SECRET undefined

These vars are only injected when auth: mode: sso is set in spec:

spec:
  auth:
    mode: sso

IMPORTANT: Do not use internalDependencies: bio-id to enable OAuth — that is incorrect. Only auth: mode: sso provisions the OAuth client.

Invalid redirect URI

The Bio-ID OAuth client is automatically registered with exactly one redirect URI:

  • Sandbox: https://{service}.sandbox.tawa.insureco.io/api/auth/callback
  • Production: https://{service}.tawa.insureco.io/api/auth/callback

Your callback route must be at /api/auth/callback. Any other path will be rejected by Bio-ID.

Use tawa oauth list and tawa oauth get <client-id> to inspect the registered redirect URIs. To add a local development URI:

tawa oauth add-uri <client-id> http://localhost:3000/api/auth/callback

DNS Not Propagating

After the first deploy to an environment, DNS can take up to 5 minutes to propagate. Use tawa status to confirm the deploy completed and the DNS record was created.

For custom domains, use tawa domain add <domain> after a successful deploy.

Deploy-Gated Tests Failing

If your catalog-info.yaml declares spec.tests and the build is marked failed but the pod is running:

  • The smoke test paths declared under spec.tests.smoke are being probed and one or more returned an unexpected status code.
  • The deployment is not rolled back — the pod continues running for debugging.
  • Check that each path listed in spec.tests.smoke returns the expected HTTP status code.
  • Fix the endpoint, commit, push, and redeploy.
spec:
  tests:
    smoke:
      - path: /health
        expect: 200
      - path: /api/ping
        expect: 200

Getting More Help

CommandWhat it does
tawa troubleshootAI-powered diagnostics for your service
tawa logs --build <id>Full build output for a specific build
tawa logsLive pod output
tawa eventsFull audit log of deploys and config changes
tawa podsPod restart count and uptime

Last updated: March 1, 2026