Operating System
macOS 15 (Sequoia), also reproduced on deployed web app (Linux/Cloud Run)
Environment (if applicable)
Chrome 143
Firebase SDK Version
12.4.0
Firebase SDK Product(s)
Auth
Project Tooling
Vite 6, React 18, TypeScript, Node.js 20
Detailed Problem Description
When a user attempts MFA sign-in via phone SMS, Firebase Auth attempts reCAPTCHA Enterprise verification before sending the SMS code. The Enterprise reCAPTCHA token is generated correctly on the client, sent in the mfaSignIn:start request, and Firebase's own backend successfully creates an assessment via the reCAPTCHA Enterprise API returning valid: true with a perfect score of 1.0. Despite this, Firebase returns INVALID_APP_CREDENTIAL (HTTP 400).
The error is not transient — it happens on every single Enterprise attempt. A reCAPTCHA v2 fallback (using RecaptchaVerifier) succeeds immediately after.
This has been reproduced with:
A custom Terraform-created SCORE-type reCAPTCHA Enterprise site key
Firebase's own managed "Key for Identity Platform reCAPTCHA integration" site key
Both fail identically. The reCAPTCHA Enterprise assessment Cloud Logs confirm the token is valid in both cases.
Configuration:
Firebase Console → Authentication → Settings → Fraud prevention → Phone authentication enforcement mode: AUDIT
reCAPTCHA Enterprise key type: SCORE (INVISIBLE/CHECKBOX are incompatible and were not used)
IAM: roles/recaptchaenterprise.agent granted to service-<PROJECT_NUMBER>@gcp-sa-identitytoolkit.iam.gserviceaccount.com
App Check: registered with reCAPTCHA Enterprise, enforcement mode: Monitoring (not enforced)
initializeRecaptchaConfig(auth) called at app startup
Steps and code to reproduce issue
Create a Firebase project with Identity Platform enabled
Enable phone MFA for users
In Firebase Console → Authentication → Settings → Fraud prevention, enable reCAPTCHA and set enforcement mode to AUDIT with a SCORE-type site key
In the web app, call initializeRecaptchaConfig(auth) at startup
Sign in with email/password as a user who has phone MFA enrolled
When the MFA challenge appears, provide a RecaptchaVerifier and call PhoneAuthProvider.verifyPhoneNumber() (or equivalent via MultiFactorResolver)
Observe mfaSignIn:start returns INVALID_APP_CREDENTIAL (HTTP 400)
Note the reCAPTCHA Enterprise assessment in Cloud Logging shows valid: true, score: 1
// firebase.ts — initialisation
import { initializeApp } from 'firebase/app';
import { getAuth, initializeRecaptchaConfig } from 'firebase/auth';
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
await initializeRecaptchaConfig(auth);
// MFA sign-in — sending SMS code
import {
RecaptchaVerifier,
PhoneAuthProvider,
PhoneMultiFactorGenerator,
} from 'firebase/auth';
const appVerifier = new RecaptchaVerifier(auth, 'send-code-button', {
size: 'invisible',
});
const phoneAuthProvider = new PhoneAuthProvider(auth);
const verificationId = await phoneAuthProvider.verifyPhoneNumber(
{
multiFactorHint: resolver.hints[0], // PhoneMultiFactorInfo
session: resolver.session,
},
appVerifier
);
// ↑ Throws: FirebaseError: Firebase: Error (auth/invalid-app-credential)
// Network: POST mfaSignIn:start → 400 INVALID_APP_CREDENTIAL
// But reCAPTCHA Enterprise Cloud Log shows: valid: true, score: 1
reCAPTCHA Enterprise Assessment Log (from GCP Cloud Logging):
{ "tokenProperties": { "valid": true, "hostname": "dev.alliediq.com.au", "action": "mfaSmsSignIn", "createTime": "2026-03-12T21:40:18.923Z" }, "riskAnalysis": { "score": 1 }, "event": { "siteKey": "6Lfx3oQsAAAAABqNr2-ov-kD_hhooUzOVFTML6JU", "userInfo": { "accountId": "+61400000000" } }}
Operating System
macOS 15 (Sequoia), also reproduced on deployed web app (Linux/Cloud Run)
Environment (if applicable)
Chrome 143
Firebase SDK Version
12.4.0
Firebase SDK Product(s)
Auth
Project Tooling
Vite 6, React 18, TypeScript, Node.js 20
Detailed Problem Description
When a user attempts MFA sign-in via phone SMS, Firebase Auth attempts reCAPTCHA Enterprise verification before sending the SMS code. The Enterprise reCAPTCHA token is generated correctly on the client, sent in the mfaSignIn:start request, and Firebase's own backend successfully creates an assessment via the reCAPTCHA Enterprise API returning valid: true with a perfect score of 1.0. Despite this, Firebase returns INVALID_APP_CREDENTIAL (HTTP 400).
The error is not transient — it happens on every single Enterprise attempt. A reCAPTCHA v2 fallback (using RecaptchaVerifier) succeeds immediately after.
This has been reproduced with:
A custom Terraform-created SCORE-type reCAPTCHA Enterprise site key
Firebase's own managed "Key for Identity Platform reCAPTCHA integration" site key
Both fail identically. The reCAPTCHA Enterprise assessment Cloud Logs confirm the token is valid in both cases.
Configuration:
Firebase Console → Authentication → Settings → Fraud prevention → Phone authentication enforcement mode: AUDIT
reCAPTCHA Enterprise key type: SCORE (INVISIBLE/CHECKBOX are incompatible and were not used)
IAM: roles/recaptchaenterprise.agent granted to service-<PROJECT_NUMBER>@gcp-sa-identitytoolkit.iam.gserviceaccount.com
App Check: registered with reCAPTCHA Enterprise, enforcement mode: Monitoring (not enforced)
initializeRecaptchaConfig(auth) called at app startup
Steps and code to reproduce issue
Create a Firebase project with Identity Platform enabled
Enable phone MFA for users
In Firebase Console → Authentication → Settings → Fraud prevention, enable reCAPTCHA and set enforcement mode to AUDIT with a SCORE-type site key
In the web app, call initializeRecaptchaConfig(auth) at startup
Sign in with email/password as a user who has phone MFA enrolled
When the MFA challenge appears, provide a RecaptchaVerifier and call PhoneAuthProvider.verifyPhoneNumber() (or equivalent via MultiFactorResolver)
Observe mfaSignIn:start returns INVALID_APP_CREDENTIAL (HTTP 400)
Note the reCAPTCHA Enterprise assessment in Cloud Logging shows valid: true, score: 1
// firebase.ts — initialisation
import { initializeApp } from 'firebase/app';
import { getAuth, initializeRecaptchaConfig } from 'firebase/auth';
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
await initializeRecaptchaConfig(auth);
// MFA sign-in — sending SMS code
import {
RecaptchaVerifier,
PhoneAuthProvider,
PhoneMultiFactorGenerator,
} from 'firebase/auth';
const appVerifier = new RecaptchaVerifier(auth, 'send-code-button', {
size: 'invisible',
});
const phoneAuthProvider = new PhoneAuthProvider(auth);
const verificationId = await phoneAuthProvider.verifyPhoneNumber(
{
multiFactorHint: resolver.hints[0], // PhoneMultiFactorInfo
session: resolver.session,
},
appVerifier
);
// ↑ Throws: FirebaseError: Firebase: Error (auth/invalid-app-credential)
// Network: POST mfaSignIn:start → 400 INVALID_APP_CREDENTIAL
// But reCAPTCHA Enterprise Cloud Log shows: valid: true, score: 1
reCAPTCHA Enterprise Assessment Log (from GCP Cloud Logging):
{ "tokenProperties": { "valid": true, "hostname": "dev.alliediq.com.au", "action": "mfaSmsSignIn", "createTime": "2026-03-12T21:40:18.923Z" }, "riskAnalysis": { "score": 1 }, "event": { "siteKey": "6Lfx3oQsAAAAABqNr2-ov-kD_hhooUzOVFTML6JU", "userInfo": { "accountId": "+61400000000" } }}