Troubleshooting: CONSENT_RECEIPT_INVALID (422)
The India DPDP Phase II Consent Manager surface verifies the signed consent receipts you persist or re-verify. When verification fails, the API rejects the request with a 422 and codeCONSENT_RECEIPT_INVALID:
Consent receipts are a tenant-owned compliance control: your Consent
Manager issues and signs the receipt, and Orbit verifies it against the
public key you registered. The opt-in / opt-out record that results lives
in your consent ledger — Orbit enforces nothing beyond the verification
itself.
Symptom map
Work through the symptom table in order — the two endpoints both surface exactly three failure shapes, and the message tells you which one fired.POST /api/v1/compliance/consent/receipts mints a receipt;
POST /api/v1/compliance/consent/receipts/:id/verify re-checks a stored one.
The registry lists
CONSENT_RECEIPT_INVALID as varies for HTTP status
because the mint endpoint rejects structurally-degenerate receipts at 422
VALIDATION_ERROR instead (a bad ISO-8601 timestamp, a malformed Base64URL
signature, an empty payload, or a payload that disagrees with the displayed
receipt fields). A structural problem gets the 422 VALIDATION_ERROR;
a cryptographic failure once structure passes gets the
CONSENT_RECEIPT_INVALID above. Only verified receipts are persisted —
verification always runs before storage.
How receipts are issued, and when the API rejects the request
TwoCONSENT_RECEIPT_INVALID paths exist:
- Mint (
POST /compliance/consent/receipts) — persist a receipt your Consent Manager signed. The manager must be registered and active; the signature must verify before anything is stored (Orbit never persists a receipt it cannot verify). - Re-verify (
POST /compliance/consent/receipts/:id/verify) — re-check a stored receipt against the issuing manager’s current key (an audit step, or a check on a suspected key rotation). The{id}accepts either the consent-record id or thereceipt_id.
consent_manager_id or a
known-but-inactive manager fires the wrong-manager throw. At re-verify,
a deleted manager row fires the no-longer-registered throw. In both
cases the signature failure means the same thing: the payload changed
after signing, or the key the platform holds is not the key that signed
(say the manager rotated keys without notifying you).
Fix workflow: unknown or inactive Consent Manager
- Register the manager under Settings → Compliance → Consent managers
(or via
POST /api/v1/compliance/consent/managers) with its machinemanager_id, HTTPS URL, and SPKI PEM public key. - Point the mint request’s
consent_manager_idat that samemanager_idvalue. - To fix manager deactivation, use
PUT /compliance/consent/managers/:idwithis_active: true.
consent_managers table missing) mint is
fail-closed with exactly this error — the read endpoints degrade to
empty / 404, but writes refuse. Re-run the provisioning migration before
minting receipts.
Fix workflow: signature verification failed
Work through these in order — each isolates one of the three distict causes:- Key rotation. The Consent Manager rotated its signing key without
telling you. Register the manager’s new public key under
Settings → Compliance → Consent managers (or
PUT /compliance/consent/managers/:idwith the newpublic_key), and ask the manager to re-issue the receipt signed with the current key. - Payload tampered in transit. The JSON you posted disagrees with what was signed — a copy-paste edit, a middleware transform, or the manager changed the payload after signing. Paste the receipt envelope exactly as the manager produced it.
- Canonicalization mismatch. Orbit canonicalizes the payload before hashing (sorted keys, insignificant-whitespace stripped — a minimal RFC 8785 JCS form, not a spec-complete implementation). If the manager signed a different serialization, ask it to sign the same sorted-key form Orbit uses.
POST /compliance/consent/receipts again. The upsert targets the same
contact_id + channel pair, so a corrected re-issue replaces the failed
attempt’s pending soft-fact with the verified one.
Fix workflow: manager no longer registered
IfPOST /receipts/:id/verify says the issuing Consent Manager is no
longer registered, the receipt still exists but its trust anchor
(consent_managers row) was deleted. Re-register the manager with the
same manager_id — re-verification then re-checks against the new row’s
key.
Still failing? Pass to support
Include in the ticket:- The
request_idfrommeta.request_idon the 422 response - Whether the failure was mint or re-verify, and the
consent_manager_idfromerror.details - The exact receipt envelope you posted (or the stored
{id}), so support can replay the structure and signature checks without asking you to reproduce