This error occurs when a user provides an incorrect SMS verification code during Firebase phone authentication. The code may be wrong, expired, or the verification ID may be invalid.
The "auth/invalid-verification-code" error is thrown by Firebase Authentication when attempting to sign in with phone number authentication and the provided SMS verification code does not match the code sent to the user. This is a client-side validation error that occurs after the user receives an SMS message with a verification code and enters it into your app. Firebase checks the code against the verification ID that was generated when the sign-in process started. If they do not match, or if the code has expired, this error is raised. The error can manifest differently across platforms (Android, iOS, Flutter, Web) but the underlying cause is the same: the verification credentials are invalid.
Go to Firebase Console > Authentication > Sign-in method tab and ensure "Phone" is enabled. If it is not, enable it and save your changes. Without this enabled, all phone authentication attempts will fail.
# No code needed - this is a Firebase Console settingWrap your phone authentication code in try-catch blocks to catch the invalid-verification-code error specifically. This allows you to display a helpful message and offer to resend the code.
// Web/JavaScript example
const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, appVerifier);
const code = prompt("Enter verification code");
try {
const result = await confirmationResult.confirm(code);
console.log("User signed in successfully");
} catch (error) {
if (error.code === "auth/invalid-verification-code") {
console.error("Invalid verification code. Please try again or request a new code.");
// Show UI to let user re-enter or resend
} else {
console.error("Sign-in failed:", error.message);
}
}// Flutter example
try {
UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(
PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
),
);
print("User signed in successfully");
} on FirebaseAuthException catch (e) {
if (e.code == 'invalid-verification-code') {
print("Invalid verification code. Please check and try again.");
// Show error message to user
} else {
print("Sign-in failed: ${e.message}");
}
}// Android (Kotlin) example
credential = PhoneAuthProvider.getCredential(verificationId, code)
try {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Log.d("PhoneAuth", "User signed in successfully")
} else {
val e = task.exception
if (e is FirebaseAuthInvalidCredentialsException) {
Log.w("PhoneAuth", "Invalid verification code")
// Show error message to user
}
}
}
} catch (e: Exception) {
Log.e("PhoneAuth", "Sign-in failed", e)
}Provide a UI element that allows users to input the verification code again. Some users may have mistyped or autocorrect may have changed the code. Display the error message clearly and give them the ability to try again without restarting the entire sign-in process.
// React example
const [code, setCode] = useState("");
const [error, setError] = useState("");
const handleConfirm = async () => {
try {
await confirmationResult.confirm(code);
// Success - navigate to next screen
} catch (err) {
if (err.code === "auth/invalid-verification-code") {
setError("The code you entered is incorrect. Please try again.");
setCode(""); // Clear the input
}
}
};
return (
<div>
<input
type="text"
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder="Enter 6-digit code"
/>
{error && <div style={{ color: "red" }}>{error}</div>}
<button onClick={handleConfirm}>Verify Code</button>
</div>
);Verification codes typically expire after 5-10 minutes. Implement a timer that shows users how much time remains, and provide a "Resend Code" button. When resending, you must request a new verification ID.
// Web example with resend logic
let verificationId = null;
let confirmationResult = null;
const sendCode = async (phoneNumber) => {
const appVerifier = window.recaptchaVerifier;
try {
confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, appVerifier);
console.log("Code sent to", phoneNumber);
// Start 5-minute timer
setTimeout(() => {
console.log("Code expired. User must resend.");
}, 300000);
} catch (error) {
console.error("Failed to send code:", error.message);
}
};
const resendCode = async (phoneNumber) => {
// Clear previous verificationId and request a new one
confirmationResult = null;
await sendCode(phoneNumber);
};// Flutter example
Final int codeExpiresSecs = 300; // 5 minutes
Final int codeResendSecs = 30; // Can resend after 30 seconds
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: codeExpiresSecs),
verificationCompleted: (credential) {
// Auto-complete if available
},
verificationFailed: (e) {
print("Verification failed: ${e.message}");
},
codeSent: (verificationId, resendToken) {
// Show input form with timer
// Enable resend button after 30 seconds
},
codeAutoRetrievalTimeout: (verificationId) {
// Code expired
},
);The verification ID must be stored securely and persisted for the entire sign-in flow. If your app crashes, is backgrounded, or the user navigates away, you may lose the verification ID, causing subsequent confirmation attempts to fail.
// Store verificationId in state during the sign-in flow
const [verificationId, setVerificationId] = useState(null);
const sendCode = async (phoneNumber) => {
const appVerifier = window.recaptchaVerifier;
try {
const confirmationResult = await signInWithPhoneNumber(
auth,
phoneNumber,
appVerifier
);
// Store the verification ID
setVerificationId(confirmationResult.verificationId);
} catch (error) {
console.error("Failed:", error);
}
};
const confirmCode = async (code) => {
try {
const credential = PhoneAuthProvider.credential(
verificationId, // Use stored ID
code
);
await signInWithCredential(auth, credential);
} catch (error) {
if (error.code === "auth/invalid-verification-code") {
console.error("Invalid code");
}
}
};During development and testing, use Firebase test phone numbers instead of real numbers. This prevents quota issues and allows you to use predetermined verification codes.
1. Go to Firebase Console > Authentication > Phone > Phone numbers for testing
2. Click "Add phone number for testing"
3. Enter a test phone number (e.g., +1 555-0100)
4. Enter a test code (e.g., 123456)
5. Use this phone number and code combination in your app during testing
// No code change needed - just use the test phone number
const testPhoneNumber = "+1 555-0100"; // From Firebase Console
const testCode = "123456"; // From Firebase Console
// This will succeed immediately without sending an SMS
await signInWithPhoneNumber(auth, testPhoneNumber, appVerifier);
await confirmationResult.confirm(testCode); // Will succeedCross-Platform Considerations: This error manifests as "PlatformException(ERROR_INVALID_VERIFICATION_CODE)" in Flutter and "FirebaseAuthInvalidCredentialsException" in Android native code. Always check the platform-specific error type in your error handler.
Production Issues: Some developers report that this error does not occur in debug mode but surfaces consistently in production builds (TestFlight, Play Store). This is typically caused by missing SHA fingerprints. Ensure your app's debug and production SHA-1 and SHA-256 fingerprints are registered in the Firebase Console under Project Settings > Your Apps > App Signing Certificate SHA-1/SHA-256.
SMS Quota Limits: Firebase enforces limits on SMS messages sent to a single phone number within a time period. If you exceed these limits, phone verification may be throttled. For development, use test phone numbers to avoid consuming quota.
ReCAPTCHA Verification: On web, phone authentication uses reCAPTCHA by default. Ensure the reCAPTCHA verifier is initialized and visible to the user before sending the code. Errors in reCAPTCHA setup can appear as invalid code errors.
Session and Timeout: The verification ID is session-specific. If your app is backgrounded for too long or the device's clock is significantly off, verification may fail. This is a security measure to prevent code reuse.
messaging/UNSPECIFIED_ERROR: No additional information available
How to fix "messaging/UNSPECIFIED_ERROR: No additional information available" in Firebase Cloud Messaging
App Check: reCAPTCHA Score Too Low
App Check reCAPTCHA Score Too Low
storage/invalid-url: Invalid URL format for Cloud Storage reference
How to fix invalid URL format in Firebase Cloud Storage
auth/missing-uid: User ID identifier required
How to fix "auth/missing-uid: User ID identifier required" in Firebase
auth/invalid-argument: Invalid parameter passed to method
How to fix "auth/invalid-argument: Invalid parameter passed to method" in Firebase