Skip to main content

Troubleshooting: QR code render failures

The three QR endpoints — GET /api/v1/qr/generate, GET /api/v1/qr/whatsapp, and GET /api/v1/qr/sms — can refuse a request at three layers (payload policy, schema, or phone validation) or fail at the render step itself. Each layer returns a different status, and only one of them is retry-safe. Match your status code to the class first, then fix the cause. If the request returned a QR image but the encoded content looks wrong, that is a payload-construction question, not a failure — see the QR generation model concept page for how each endpoint assembles its payload.

Symptom map

Read error.code on the JSON envelope to confirm the class; a png default response means you see these envelopes only when you pass format=json or when the request failed before any image was produced.

Cause → fix

Pre-checks before you call

Run these before any retry to avoid burning the one retry-safe attempt:
  • Size bounds: size must be an integer between 50 and 1024 pixels (default 300). The output PNG is always square.
  • Payload length: data on /qr/generate caps at 2048 characters (the QR version-40 byte ceiling); message on the phone endpoints caps at 1024 characters.
  • Phone shape: phone must look like an international number — + plus digits, spaces, parentheses, dashes, or dots only — and then pass the dialable-number check.

Retry discipline

Deterministic failures never succeed on repeat. Only the 502 is retry-safe.
  • 400 and 422 classes: retry exactly zero times until the payload changes. A repeat of the same request returns the same envelope.
  • 502 QR_RENDER_FAILED: retry once with backoff. If it persists, treat it as a platform-side fault and escalate.

What not to do

  • Do not retry the pseudo-scheme rejection. The filter is a security policy, not a transient gate — re-encoding to an allowed scheme is the only fix.
  • Do not loop the 502. One retry is the shape defined here; a client that retries in a tight loop turns a render-side fault into a rate-limit problem on top.
  • Do not bypass the 422 with a raw client. If your integration retries 422s, strip that path — the envelope’s details.issues tells you exactly which field to correct.

Escalation bundle

Open a support ticket when the 502 QR_RENDER_FAILED persists after one retry. Include:
  1. Tenant ID (dashboard → Settings → Organization; API → GET /api/v1/me returns it as organizationId)
  2. meta.request_id from the failing envelope
  3. Endpoint (/qr/generate, /qr/whatsapp, or /qr/sms)
  4. Parameter summary — the size, format, and whether phone or data was involved (do not paste the full payload if it contains customer data)

See also