Skip to main content

Troubleshooting: BYOK_KEY_UNAVAILABLE (409) and DECRYPTION_FAILED (502)

A BYOK-enforced tenant field-encryption call (encrypt or decrypt) fails closed with a 409 and code BYOK_KEY_UNAVAILABLE when your customer-managed key cannot serve the request. The read-side sibling is a 502 with code DECRYPTION_FAILED, which signals a ciphertext problem rather than a key-lifecycle problem:
This page maps each cause to the check you can run yourself. For the concept and lifecycle behind the error — register, activate, rotate, revoke — see Customer-Managed Keys (BYOK), and the dashboard walkthrough at Customer-Managed Keys guide.
BYOK is a tenant-owned control: you hold the key in your own KMS and Orbit stores only the reference. The refuse below is the platform honoring your recorded policy, not a platform fault — when it can be resolved from your side, this page tells you how.

Cause table

Read the current BYOK record with GET /api/v1/compliance/byok to tell the causes apart — the state (pending / active / revoked), enforced flag, and fingerprint decide which row applies. The lifecycle itself is documented on the BYOK concept page: pending → active → revoked, with rotate available from pending or active. Revoke is refused on an already-revoked key (409 BYOK_ALREADY_REVOKED), and re-enabling after revocation means registering anew (PUT), not un-revoking.

Decision checklist

Work through these in order before you change anything:
  1. Read the record. GET /api/v1/compliance/byok and note state and enforced. Any authenticated user can read it; it never echoes the raw reference, only the truncated fingerprint.
  2. Match the state to a table row. revoked → re-register; pending → activate; active with the error on a fresh deploy → provisioning race; active and stable → KMS reachability or the read-side mismatch.
  3. Confirm enforce flips on only with active. Activation is the only path that can set enforce: true — re-check that it was run with enforce: true in the same call, not toggled later against a pending key.
  4. For ENCRYPTION_FAILED / DECRYPTION_FAILED, do not retry. The write-side failure (IV or authTag generation failed) and the read-side 502 are not retry-safe. Open a ticket with the request_id from meta.request_id on the response, exactly as the FAQ entry for DECRYPTION_FAILED instructs.

What NOT to do

  • Do not disable enforce to bypass the refuse. The refuse is your recorded policy doing its job; weakening it to get the call through leaves audit evidence that you ran outside your own policy, and a revoked key can never be re-enabled that way — re-register instead.
  • Do not rotate again while a rotate is in flight. For an enforced key, rotate re-wraps the internal data-encryption key under the new reference; issuing another rotate before the first completes compounds the failure. Resolve the current rotation first — if it was refused with 409 BYOK_REWRAP_FAILED, treat that as the blocker.
  • Do not re-paste the same ciphertext. On a 502 DECRYPTION_FAILED, the stored envelope pointed at a pre-rotate key. Re-reading it returns the same error every time.
  • Do not expect revocation to undo itself. Revocation destroys the wrapped DEK and clears enforce; nothing short of a fresh PUT restores BYOK.

When to escalate

Escalate to support@devotel.io when:
  • The cause row is KMS unreachable and you have confirmed the KMS endpoint is up, the reference exists, and the decrypt grant on Orbit’s service identity is intact — then the resolution failure is on the platform side.
  • Any 502 DECRYPTION_FAILED — stale ciphertext needs re-encryption onto the current key, which only the platform can perform.
  • Provisioning did not self-heal after one retry of POST /compliance/byok/activate.
Include in the ticket:
  • The request_id from meta.request_id on the 409/502 response
  • The fingerprint from GET /compliance/byok (never the raw reference)
  • The lifecycle state and enforced values at failure time
  • For KMS-reachability suspects: provider name and confirmation that the key/alias exists and the grant is active

  • Customer-Managed Keys (BYOK) — lifecycle, provider grammar, and the exact scope of enforce.
  • Customer-Managed Keys guide — the dashboard walkthrough for the same lifecycle.
  • Error Codes reference — the BYOK_KEY_UNAVAILABLE, ENCRYPTION_FAILED, and DECRYPTION_FAILED rows and the other BYOK conflict codes (BYOK_NOT_FOUND, BYOK_NOT_PENDING, BYOK_ALREADY_REVOKED, BYOK_REWRAP_FAILED).