Troubleshooting
Symptom first, cause second. Quote the X-Request-ID from the failing response whenever you escalate.
API calls
| Symptom | Cause |
|---|---|
401 INVALID_API_KEY | header missing, key doesn't start with iss_/ver_, wrong secret, or the key was revoked |
401 API_KEY_EXPIRED | key had a configured expiry that has passed |
403 PERMISSION_DENIED | key belongs to a different issuer, verifier or organization than the one in the URL |
422 on initiate-verification | metadata.redirectUri missing; one of redirectUri or redirect_uri is required |
400 offer too large | credentialOfferMode: "by_value" with an offer over the inline limit — use auto |
404 on status or diagnostics | wrong offer/verification ID, or flow diagnostics aren't enabled on this deployment — ask the operator |
422 with a validation envelope | request body failed schema validation; read errors[].pointer |
Wallet flows
| Symptom | Cause |
|---|---|
| Wallet cannot open the offer | the string is a deep link, not a URL — render it as a QR code or an HTTPS bridge link |
| Wallet rejects the credential | platform root CA not installed on the device — see Testing |
| Wallet cannot resolve the offer | it does not support credential_offer_uri; force credentialOfferMode: "by_value" if the offer is small enough |
Token exchange fails on tx_code | the offer was created with userPinRequired: true and the holder must enter the returned transactionCode; it is never in the offer email |
mso_mdoc request fails on a GET request URI | some mdoc DCQL queries require requestUriMethod: "post" — don't force "get" |
| Nothing reaches your host | wallets need public HTTPS |
Stuck states
| Symptom | Cause |
|---|---|
Issuance status stays pending | the wallet never exchanged the pre-authorized code; the offer moves to expired after 10 minutes |
Verification stays initiated | the wallet never posted a response; it expires after 15 minutes, 60 for email delivery |
Verification is failure | read failureReason, then the diagnostics timeline |
| No webhook arrives | check Developers → Webhooks: endpoint on, URL resolves to a public IP; read the delivery attempts |