Troubleshooting
Connection and pairing
| Symptom | Likely cause | Fix |
|---|---|---|
GET /qr returns 409 QR_NOT_AVAILABLE right after connect | Pairing is starting (1–2 s) | Retry after a second; check status |
Status stays CONNECTING | No worker owns the instance (worker down or at WORKER_MAX_SESSIONS) | Check worker health and whatstig_worker_sessions_active; add a worker |
DISCONNECTED with QR_TIMEOUT | QR not scanned within ~3 min | Call connect again and scan promptly |
| Phone says "couldn't link device" | Phone offline, old WhatsApp version, too many linked devices (max 4) | Update WhatsApp, remove an old linked device, retry |
LOGGED_OUT / LOGGED_OUT_FROM_PHONE | Device removed on the phone, or WhatsApp invalidated the session | Relink with connect |
LOGGED_OUT / BAD_SESSION | Stored session unusable (e.g. after restoring an old backup) | Relink |
DISCONNECTED / CONNECTION_REPLACED | The same session was opened elsewhere (another tool using the same credentials) | Stop the other client, then reconnect |
RESTRICTED | WhatsApp banned/restricted the number | Cannot be fixed by WhatsTIG; appeal in the WhatsApp app; review sending practices |
RECONNECTING / RECONNECT_EXHAUSTED | 12 fast reconnects failed (network or WhatsApp outage); the worker keeps retrying every ~5 min | Nothing: it reconnects by itself when the outage ends. Call reconnect to retry immediately |
| Instances reconnect after each deploy | Expected: deploys restart sockets (no QR needed) | — |
Many whatstig_session_lease_lost_total | Worker overloaded (event-loop lag) or database latency causing missed heartbeats | Add workers, check DB, consider a larger LEASE_TTL_MS |
Sending
| Symptom | Likely cause | Fix |
|---|---|---|
Messages stay QUEUED | Instance not CONNECTED, or pacing limit (default 20/min per instance) | Check instance status; tune INSTANCE_MESSAGES_PER_MINUTE or the instance's rate_policy |
FAILED / EXPIRED | Instance was disconnected longer than the message TTL | Reconnect; use appropriate expiresInSeconds |
FAILED / RECIPIENT_NOT_ON_WHATSAPP | Number has no WhatsApp | Correct the number / use another channel |
400 INVALID_RECIPIENT | Number not valid in international format | Include the country code or set the project's default country |
UNKNOWN | Worker stopped mid-send, or an unexpected provider error | See reliability guide; check worker logs for the message ID |
Stays SENT, never DELIVERED | Recipient offline, or blocked/has no receipts; or the number blocked you | Nothing to fix; receipts are not guaranteed |
429 BACKLOG_LIMIT_REACHED | Too many queued messages in the project | Slow down producers; check why the instance is not sending |
409 IDEMPOTENCY_KEY_REUSED | Same key used for different content | Use a unique key per logical message |
Webhooks
| Symptom | Fix |
|---|---|
Deliveries failed with UnsafeUrlError | URL resolves to a private address or is not HTTPS — use a public HTTPS URL |
| Signature mismatch | Verify against the raw body (no re-serialization), correct secret (rotated?), clock in sync (±5 min) |
Endpoint disabled | 100 consecutive failures — fix the endpoint, PATCH { "enabled": true }, replay dead deliveries |
| Duplicates | Expected (at-least-once): deduplicate on event id |
| Out-of-order events | Expected: use occurredAt and status rank |
Dashboard and auth
| Symptom | Fix |
|---|---|
| No verification email | Check SMTP_URL and the API logs ("SMTP_URL not configured" means emails are only logged) |
403 CSRF_REJECTED | The dashboard origin is not PUBLIC_APP_URL/TRUSTED_ORIGINS, or a proxy strips the Origin header |
| Signed out repeatedly | BETTER_AUTH_SECRET differs between API replicas, or cookies blocked because PUBLIC_APP_URL scheme mismatches |
Platform
| Symptom | Fix |
|---|---|
| Service exits with "Invalid configuration" | The listed variables are missing/invalid; compare with .env.example |
Decryption failed in worker logs | WHATSTIG_ENCRYPTION_KEYS missing the key version used for stored data — restore the key |
API 503 on readiness | PostgreSQL or Redis unreachable |
| High event-loop lag on a worker | Too many sessions for one process — add workers / lower WORKER_MAX_SESSIONS |
When reporting an issue, include the requestId (API responses), instance ID, message ID and approximate time.