Go to developer

Troubleshoot Partner 2FA

Enrollment, challenges, one-shot verification tokens, disable behavior, and Partner API failures.

On this page

Partner 2FA failures are usually enrollment state, challenge lifecycle, or one-shot token handling.

Enrollment stays pending

Symptom

pollEnrollment / waitForEnrollment never reaches an enrolled terminal state.

Most likely causes

  1. User abandoned the enrollment QR/link
  2. Polling a different enrollmentId than enable2FA returned
  3. Enrollment expired

How to diagnose

  • Inspect pollEnrollment status and terminal flags
  • Confirm the user opened the enrollment URL
  • Check for KeyraEnrollmentExpiredError / expired status
Diagnostic flow
  1. Did enable2FA return an enrollmentId?
  2. Are you polling that same id?
  3. Did the user open the enrollment URL?
  4. Is status expired/cancelled/failed?
  5. Start a new enable2FA if terminal failure

How to fix

  • Start a new enable2FA.
  • Keep enrollmentId stable in UI state until terminal.

User is reported as not enrolled

Symptom

get2FAStatus shows not enrolled, or createChallenge returns not_enrolled.

Most likely causes

  1. Never enrolled
  2. Disabled/revoked
  3. Different externalUserId or project

How to diagnose

  • Compare project + externalUserId across enroll and challenge.
  • Check for prior disable2FA.

How to fix

  • Complete enrollment.
  • Re-enroll after disable.

Challenge stays pending

Symptom

Challenge remains PENDING until timeout/expiry.

Most likely causes

  1. User never opened/scanned challengeUrl
  2. Wrong URL displayed
  3. Challenge already expired
  4. Polling a different challengeId

How to diagnose

  • Poll status for expired
  • Verify challengeId continuity
  • Confirm device completed hosted verification
Diagnostic flow
  1. Is the challenge expired?
  2. Did the user open/scan the challenge URL?
  3. Did the device complete verification?
  4. Are you polling the ORIGINAL challenge ID?
  5. Inspect status / errors

How to fix

  • Re-display QR quickly.
  • Start a new challenge if expired.
  • Use waitForChallengeApproval.

Verification token is missing / disappeared

Symptom

User approved, but verificationToken is undefined on later polls.

Most likely causes

  1. verificationToken is one-shot on poll when status becomes approved
  2. Subsequent polls after first approved response omit the token
  3. UI polled again after capturing once and discarded the first payload

How to diagnose

  • Confirm status === approved on the poll that returned the token
  • Check whether a later poll ran and overwrote state with a token-less body
Diagnostic flow
  1. Was status ever approved?
  2. Did any poll response include verificationToken?
  3. Did a later poll run after that?
  4. Use waitForChallengeApproval and consume once

How to fix

  • Use waitForChallengeApproval() which waits until approved && verificationToken present
  • Store the token immediately, then call consumeChallenge once

User approved but application does not continue

Symptom

KEYRA challenge is approved, but login UX never finishes.

Most likely causes

  1. Backend never called consumeChallenge
  2. Lost one-shot verificationToken
  3. Started a new challenge on “complete” instead of consuming
  4. App session not created after consume

How to diagnose

  • Log challengeId continuity.
  • Confirm consume runs exactly once.
  • Confirm Set-Cookie / session after consume.

How to fix

  • Do not create a new challenge after approval.
  • Use waitForChallengeApproval + consumeChallenge.

Disable 2FA succeeded but an existing challenge still works

Symptom

After disable2FA, an in-flight challenge can still be completed.

Most likely causes

  1. Current behavior: disable does not cancel already in-flight challenges
  2. App still accepting consume for a challenge started before disable

How to diagnose

  • Confirm challenge was created before disable.
  • Check whether your app still polls/consumes it.

How to fix

  • Stop starting new challenges after disable
  • In your app, reject incomplete challenges for revoked users if required by policy