Troubleshooting
Symptoms you will actually hit on PandaStack, what causes them, and how to fix them — HTTP status codes, failed deploys, sandboxes that will not start, and database connection problems.
Every entry below is a real failure, with the symptom you see first. If you know the HTTP status or the error text, search this page for it.
Nothing here is hypothetical — each item is a failure mode that occurs in practice, with the specific fix.
Quick triage by HTTP status
| Status | Usually means | Go to |
|---|---|---|
401 | Missing or wrong API key | Authentication |
402 | Free credit exhausted; workspace paused | 402 Payment Required |
404 | Wrong ID, or resource belongs to another workspace | Wrong workspace |
411 | POST sent with no body through the edge | 411 Length Required |
502 | No agent could take the request — usually capacity | 502 Bad Gateway |
503 | App is paused (out of credit) | App serves 503 |
Billing and quota
402 Payment Required: "free quota exceeded"
Symptom. Creating a sandbox, app, or database returns:
{ "error": "free quota exceeded",
"detail": "This account has used its free credit. Add a payment method to keep creating sandboxes." }Cause. Your workspace used its full monthly free credit ($5.40). At 100%, compute stops: running resources are paused and new creates are refused. This is a deliberate cost guard — it stops runaway spend rather than billing you for it.
Fix. Add a payment method or upgrade. The pause lifts on the next reconcile (within about a minute) and your resources resume where they left off. If you would rather wait, the free credit resets at the start of each month and the pause lifts automatically.
Your data is safe. Nothing is deleted when you run out of credit — not on a timer, not after a grace period. Code, data, volumes, and settings are kept for as long as the workspace exists. See Billing.
Your app URL returns 503 "This app is paused"
Symptom. Visitors get a plain page saying the app is paused, with
Retry-After set. The X-Pandastack-App: suspended response header confirms it.
Cause. The workspace is out of free credit, so the app's compute is stopped. A paused app is deliberately not woken by traffic — otherwise it would burn credit on every visit.
Fix. Same as above: add a payment method, or wait for the monthly reset. The app resumes automatically; you do not need to redeploy.
The 503 is intentional rather than a 404: it tells crawlers the app is
temporarily unavailable and coming back, so your URL is not de-indexed.
Capacity
502 Bad Gateway on create
Symptom. POST /v1/sandboxes returns 502 — often after several creates
that succeeded seconds earlier.
Cause. No agent had room. Each sandbox reserves its template's baked
memory (the base template is 4 GiB), so a host's RAM is the real ceiling, not
any sandbox count limit. On a small fleet you can hit this after only a handful
of concurrent sandboxes.
Fix.
- Delete sandboxes you are no longer using —
DELETE /v1/sandboxes/{id}. Capacity frees immediately. - Give sandboxes a
ttl_secondsso abandoned ones reap themselves. - Use a smaller template where you can:
code-interpreterandagentbake at 2 GiB versusbaseat 4 GiB, so they fit roughly twice as densely. - Retry with backoff —
502here is transient, not a permanent rejection.
Concurrency is bounded by fleet memory. If you need a specific concurrency figure for a workload, measure it against your own fleet rather than assuming a number — and get in touch before relying on high concurrency in production.
Deploying apps
Build fails in npm install with node-gyp / "No module named 'distutils'"
Symptom. The deploy log ends with a native build failure:
npm error command sh -c prebuild-install || (node-gyp rebuild ...)
npm error prebuild-install warn install No prebuilt binaries found (target=24.x ...)
npm error ModuleNotFoundError: No module named 'distutils'
npm error gyp ERR! not okCause. One of your dependencies ships a native addon with no prebuilt binary
for the Node version the build resolved, so npm fell back to compiling it with
node-gyp — and the build image's Python is 3.12+, which removed distutils.
Fix. Pin the runtime your dependency actually publishes binaries for. Most packages target the current LTS:
[tools]
node = "22"
python = "3.11"Node 22 is the version most native addons ship prebuilt binaries for, so nothing
compiles. The python pin is a safety net for the case where something still
does build from source.
.nvmrc is not read. Runtime versions come from mise.toml or
.tool-versions. A repo pinning Node only in .nvmrc silently gets the
default, which is the most common cause of this failure.
Deploy succeeds, then the health check fails
Symptom. The build finishes but the deploy ends at
waiting for app to listen on :<port>.
Cause. Almost always one of two things:
- The app binds
127.0.0.1. The health check and the proxy both reach your app over the VM's network interface, so a loopback-only listener is unreachable — exactly as it would be behind any container platform or load balancer. - The app ignores
$PORT. PandaStack injectsPORT; if your server hardcodes a different one, nothing is listening where we look.
Fix. Bind all interfaces and honour $PORT:
app.listen(process.env.PORT || 3000, "0.0.0.0");uvicorn.run(app, host="0.0.0.0", port=int(os.environ["PORT"]))Build runs out of memory
Symptom. The build dies abruptly, often with JavaScript heap out of memory
or a bare Killed.
Cause. Apps run at a fixed 4 GiB / 8 vCPU. Firecracker cannot resize a
VM at snapshot restore, so an app's size comes from its template's baked size —
setting memory_mb on the app does not change what it actually gets.
Fix. Reduce peak build memory: cap the Node heap
(NODE_OPTIONS=--max-old-space-size=3072), disable source maps for production
builds, or build fewer targets at once. If a build genuinely needs more than
4 GiB, it cannot run on the stock base template — bake a custom template with
more memory (--memory-mb) and set it on the app.
Files my app wrote have disappeared
Symptom. Uploads, generated files, or a SQLite database vanish after a redeploy — or after the app has been idle.
Cause. An app's local disk is ephemeral. A redeploy provisions a fresh sandbox, and scale-to-zero replaces the running VM as well. Only what is in your repository plus what the build produces survives.
Fix. Keep durable state outside the app:
- Files and uploads → S3-compatible object storage.
- Relational data → a managed PostgreSQL database.
This is the same constraint as any ephemeral-filesystem platform; design for it rather than around it.
Databases
Connection refused, or connection_url missing from the API response
Symptom. GET /v1/databases/{id} returns the database with
status: "hibernated" and no connection_url.
Cause. Idle databases auto-suspend to stop billing. A suspended database has no live endpoint until it is woken.
Fix. Either connect anyway — the proxy wakes the database on connect — or
wake it explicitly and poll until status is running:
curl -X POST https://api.pandastack.ai/v1/databases/$ID/wake \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
-H "Content-Type: application/json" -d '{}'To keep a database from ever suspending, set always_on:
curl -X PATCH https://api.pandastack.ai/v1/databases/$ID \
-H "Authorization: Bearer $PANDASTACK_API_KEY" \
-H "Content-Type: application/json" -d '{"always_on": true}'411 Length Required on a POST
Symptom. A POST with no body — wake, failover, reset-credentials —
returns 411, with no JSON body.
Cause. The edge rejects a bodyless POST before it reaches the API.
Fix. Always send a body, even an empty object, and set the content type:
curl -X POST .../wake -H "Content-Type: application/json" -d '{}'TLS errors connecting to a managed database
Symptom. Your client refuses the connection, or reports a certificate problem.
Cause. Managed databases require TLS. Clients that default to plaintext fail to connect at all.
Fix. Enable TLS normally — the certificate chains to a public CA, so no custom root certificate and no verification bypass is needed:
psql→ append?sslmode=requireto the URL.- Node (
pg) →ssl: true. - Directus and similar →
DB_SSL=true.
If a tool asks you to disable certificate verification to connect, that is a misconfiguration on the client side, not a requirement of the service.
Authentication
401 Unauthorized
Cause. Missing, malformed, or revoked API key.
Fix. Send the key as a bearer token, and confirm the variable is actually set in the shell you are running in:
curl https://api.pandastack.ai/v1/sandboxes \
-H "Authorization: Bearer $PANDASTACK_API_KEY"The environment variable the SDKs and CLI read is PANDASTACK_API_KEY. An
older PANDASTACK_TOKEN name was removed — if you are following an outdated
snippet, that is why nothing is authenticating.
404 on a resource you know exists
Cause. Resources are scoped to a workspace. A valid ID belonging to a different workspace reads as "not found" — deliberately, so IDs cannot be probed across tenants.
Fix. Confirm you are using the key for the right workspace, and that your
current organization is the one that owns the resource (GET /v1/me).
Still stuck?
- Build and runtime logs are the fastest signal:
GET /v1/apps/{id}/deploys/{deployID}/logsfor the build, andGET /v1/apps/{id}/runtime-logsfor your app's own stdout/stderr. - For a sandbox,
GET /v1/sandboxes/{id}/logsreturns the Firecracker console — useful when a VM never becomes reachable. - Email hello@pandastack.ai with the resource ID and the timestamp; those two things make an incident traceable end to end.