Errors, Rate Limits & Troubleshooting

Every error family on the platform, what causes it, and how to get unstuck.

Response envelopes by API familylink

FamilyError shape
Business REST (support tickets, secret manager, auth verify){ "statusCode": 401, "error": "Unauthorized", "message": "…", "correlationId": "req-…", "timestamp": "…" } (+ details on validation errors)
BugWatch ingest / symbols / deploy{ "error": "…" } with the HTTP status carrying the semantics
OTLP (/v1/logs · /v1/traces · /v1/metrics){ "partialSuccess": { "rejectedLogRecords": 0, "errorMessage": "…" } } with the mapped status
Prometheus query{ "status": "error", "errorType": "unauthorized" | "execution", "error": "…" }
Jaeger{ "data": null, "errors": [{ "msg": "…" }] }
MCPJSON-RPC error object, e.g. { "jsonrpc": "2.0", "error": { "code": -32001, "message": "…" }, "id": null }

Every REST response echoes X-Correlation-ID (send your own x-correlation-id header to propagate yours). Quote it when contacting support — it is the fastest path to your exact request in the logs.

Error cataloguelink

StatusMessage you'll seeCauseFix
401Missing API key.No x-api-key headerSend x-api-key: KEYID:secret
401Invalid API key format. Expected: <keyId>:<secretKey>Key ID sent without the secret to a server endpointUse the full keyId:secret string (shown once at creation)
401Invalid or inactive API keyUnknown key ID, revoked, or expiredCheck Dashboard → API Keys; create/rotate if needed
401Invalid API keyKey ID exists but the secret is wrongRe-copy the secret; rotating invalidates old secrets immediately
403Business account is not activeOrg suspendedResolve account status in the dashboard
403API key does not have access to BugWatchKey has no bugwatch product scopeRecreate/edit the key with the right product
403API key lacks the … permissionKey is missing a granular scope (ingest:write, deploy:write, symbols:*)Add the scope, or use the project's DSN key
403origin_not_allowedBrowser ingest Origin not in the project's allowed originsAdd your site origin at Dashboard → project → Settings (empty list = unrestricted)
400use the DSN key from Settings > DSN keysKey has zero or multiple BugWatch resource scopesIngest requires a per-project DSN key, not an org-wide key
404BugWatch project not foundProject deleted or key's resource scope staleRecreate a DSN key from a live project
404deployment not found / project not foundWrong deployId or another project's keyIds are per-project; use the id returned by Start deployment
409(symbols complete)The file was never PUT to uploadUrlPUT the bytes, then call complete
429rate_limited / Too Many RequestsSee limits belowHonour Retry-After; batch events instead of sending singly
413Payload too largeBody over the per-route capIngest ≤ 2 MB, OTLP ≤ 4 MB, RUM ≤ 64 KB — split batches

Rate limitslink

SurfaceLimitKeyed byOn 429
REST API (business endpoints)100 requests / 60 sorganisationRetry-After, X-RateLimit-Limit, X-RateLimit-Remaining: 0, X-RateLimit-Reset headers
OTLP / Prometheus / Jaeger / RUM600,000 / minBugWatch projectprotocol-shaped 429 body, no headers
Mobile ingest12,000 / 60 sBugWatch project{ "error": "rate_limited" }

Successful business-REST responses carry X-RateLimit-Limit only — don't parse for a remaining count on 2xx.

Troubleshooting quick pathslink

  • Works in curl, fails in the browser → browsers must use the session flow (x-bugwatch-session), never x-api-key. The API's CORS policy does not accept x-api-key from browsers by design.
  • Browser ingest suddenly 403s → session tokens expire after ~1 h. Re-fetch from your mint endpoint on 403 and retry once.
  • Mobile events silently missing → device clock skew: tokens are rejected if iat is > 60 s in the future or past expiry (5 min). The SDKs re-sign per batch, so persistent loss usually means a rotated mobileAppSecret — re-issue credentials to the app.
  • Events accepted (202) but not visible → check the key's BugWatch environment (test-mode keys write to the project's non-production env), then eventId dedup (duplicates within 10 min increment deduped, not ingested).
  • Stack traces unreadable → symbols: mappings/source maps match on release + platform (must equal the SDK's release exactly); Apple/native match by debug UUID. Check Get upload status for CHECKSUM_MISMATCH, UNRECOGNIZED_ARCHIVE, ARCHIVE_PLATFORM_MISMATCH, then Reprocess to fix already-captured crashes.
  • Webhook receiver never fires → destination must be public HTTPS (private/internal IPs are rejected), and delivery is single-shot with a 5 s timeout — a cold-starting receiver misses events.
  • Chat widget button never appears → the widget hides until key auth passes; check the onAuth callback. Rejection reasons surface as MISSING | MALFORMED | UNKNOWN_ENVIRONMENT | KEY_NOT_FOUND | INACTIVE | EXPIRED | SECRET_MISMATCH | ORG_NOT_FOUND.
  • AI chat replies with a manipulation warning → the platform scans prompts for injection; malicious content is rejected (and for signed-in dashboard users, repeated attempts block the account — a super-admin must lift it).