Firebase Auth error codes for web sign-in: causes and fixes

Updated Oct 27, 2026 · Pewterkit Guides

Every Firebase Auth error in the web SDK has an error.code string such as auth/unauthorized-domain. That code, not the message, is what your app should check. Find your code in the table below for the plain-English cause and fix, then use the React snippet to show users a useful message.

How Firebase Auth errors are shaped

  • Sign-in calls such as signInWithPopup() and getRedirectResult() reject with an AuthError. It extends FirebaseError and carries code, message and customData (appName, plus email, phoneNumber or tenantId when known).
  • The long, readable messages live in the SDK's debugErrorMap. Firebase's reference says prodErrorMap is the default, so with a plain getAuth() the message is usually just Firebase: Error (auth/...). You can opt into the long messages while debugging with initializeAuth(app, { errorMap: debugErrorMap }). Either way, branch on error.code.
  • The SDK exports an AuthErrorCodes map for comparisons. Firebase notes that you can't tree-shake individual keys, so importing it can make your bundle much larger. Comparing against string literals avoids that.

Watch out for this naming trap

Two AuthErrorCodes keys look like they've been swapped. These values match the official AuthErrorCodes reference and the SDK source:

AuthErrorCodes key Actual error.code value
AuthErrorCodes.INVALID_ORIGIN "auth/unauthorized-domain"
AuthErrorCodes.UNAUTHORIZED_DOMAIN "auth/unauthorized-continue-uri"

So error.code === AuthErrorCodes.UNAUTHORIZED_DOMAIN will not catch the common "domain not authorized" sign-in error. Use "auth/unauthorized-domain" (or AuthErrorCodes.INVALID_ORIGIN).

Firebase web sign-in error codes: cause and fix

Codes and SDK messages are from the Firebase JS SDK (@firebase/auth) as of Oct 2026. Console paths follow Firebase's current docs (Security > Authentication). Older guides say Build > Authentication.

Error code What it means How to fix it Detailed guide
auth/unauthorized-domain The page's domain isn't in your project's list of domains allowed for OAuth sign-in. Add the exact hostname under Security > Authentication > Settings > Authorized domains > Add domain. Authorized domains
auth/unauthorized-continue-uri The continue URL in an email action (password reset, email link) uses a domain that isn't authorized. Add that URL's domain to the same Authorized domains list. n/a
auth/popup-blocked The SDK couldn't connect to the popup, which usually means the browser blocked it. MDN notes popups must open in direct response to user input. Call signInWithPopup() straight from the click handler, with no await before it, or fall back to signInWithRedirect(). auth/popup-blocked
auth/popup-closed-by-user The user closed the popup before sign-in finished. Treat it as a cancel. Don't show an error. auth/popup-closed-by-user
auth/cancelled-popup-request A second popup was opened while one was still pending (for example, a double click). Disable the sign-in button while a popup is open. auth/cancelled-popup-request
auth/operation-not-allowed The sign-in provider is turned off for this Firebase project. Go to Security > Authentication > Sign-in method, enable the provider (for example Google) and click Save. n/a
auth/auth-domain-config-required authDomain is missing from the config passed to initializeApp(). Copy the full config from your Firebase project settings, including authDomain. authDomain explained
auth/invalid-api-key The apiKey in your config is wrong or empty. Re-copy it from project settings. If it comes from an env var, check the build exposes it to the browser (VITE_ prefix in Vite, NEXT_PUBLIC_ in Next.js). n/a
auth/app-not-authorized Your API key isn't allowed to use Firebase Auth from this domain. Review the API key's restrictions in the Google Cloud console and allow this site. n/a
auth/invalid-oauth-client-id The OAuth client ID is invalid or doesn't match the API key. Use the Google client ID that belongs to the same project as your API key. n/a
auth/network-request-failed A network problem: timeout, dropped connection or unreachable host. Check the connection and retry. In developer tools, look at the Network tab for a blocked or failed request. n/a
auth/timeout The operation timed out. Retry, and check the network as above. n/a
auth/internal-error A generic internal error. The code alone doesn't say why. Log the whole error (code, message, customData) and check the Network tab for a failing request. Recheck your config values. n/a
auth/web-storage-unsupported The browser isn't supported, or third-party cookies and site data may be disabled. Ask the user to allow site data for your site or try another browser. Show a clear message instead of a blank screen. n/a
auth/operation-not-supported-in-this-environment location.protocol must be http, https or chrome-extension, and web storage must be enabled. Serve the page over http(s) (for example from a local dev server), not from file://. n/a
auth/redirect-cancelled-by-user The user cancelled the redirect before sign-in finished. Treat it as a cancel. n/a
auth/redirect-operation-pending A redirect sign-in is already in progress. Don't call signInWithRedirect() again until the first one has finished. n/a
auth/account-exists-with-different-credential With "One account per email address" on, the email already belongs to a user who signed in another way. Sign the user in with their existing method, then link the pending credential from GoogleAuthProvider.credentialFromError(error). n/a
auth/credential-already-in-use You tried to link a credential that's already attached to another user. Sign in with that credential instead, or merge the accounts in your own code. n/a
auth/invalid-credential The supplied credential is incorrect, malformed or expired. In some setups, a wrong email or password also returns this code. Get a fresh credential and retry. For passwords, show a generic "wrong email or password" message. n/a
auth/user-disabled An administrator disabled this account. Re-enable it in the Firebase console's Users list if that was a mistake. n/a
auth/too-many-requests Requests from this device were blocked after unusual activity. Wait, then try again later. n/a
auth/requires-recent-login A sensitive action needs a recent sign-in. Re-authenticate the user (for example with reauthenticateWithPopup()), then retry. n/a
auth/user-token-expired The user's credential is no longer valid. Ask the user to sign in again. n/a

The auth/unauthorized-domain error has host-specific guides: localhost, Vercel and Netlify.

Errors that aren't Firebase error codes

Some sign-in failures never reach your catch block as an auth/... code, because they appear on a Google or Firebase page instead:

What you see Where it comes from Guide
Error 400: redirect_uri_mismatch Google's OAuth screen: the redirect URI isn't listed on your OAuth client redirect_uri_mismatch
"Unable to process request due to missing initial state" Firebase's sign-in helper page after a redirect missing initial state
"The requested action is invalid." Firebase's sign-in helper page The requested action is invalid

Handle Firebase Auth errors in React

This button maps codes to friendly messages, stays quiet when the user cancels, and stays disabled while a popup is open, which prevents auth/cancelled-popup-request.

// GoogleSignInButton.jsx
import { useState } from "react";
import { FirebaseError } from "firebase/app";
import { getAuth, GoogleAuthProvider, signInWithPopup } from "firebase/auth";

// null = user cancelled; don't show anything.
const MESSAGES = {
  "auth/popup-closed-by-user": null,
  "auth/cancelled-popup-request": null,
  "auth/popup-blocked":
    "Your browser blocked the sign-in window. Allow pop-ups for this site and try again.",
  "auth/unauthorized-domain":
    "Sign-in isn't set up for this web address yet.",
  "auth/operation-not-allowed":
    "Google sign-in is turned off for this app.",
  "auth/network-request-failed":
    "We couldn't reach the sign-in service. Check your connection and try again.",
  "auth/account-exists-with-different-credential":
    "You already have an account with this email. Sign in the way you did before.",
  "auth/user-disabled": "This account has been disabled.",
  "auth/too-many-requests": "Too many attempts. Please wait and try again.",
};

export function messageFor(err) {
  if (!(err instanceof FirebaseError)) return "Something went wrong. Please try again.";
  return err.code in MESSAGES
    ? MESSAGES[err.code]
    : "Sign-in failed. Please try again.";
}

export default function GoogleSignInButton() {
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState(null);

  async function handleClick() {
    setError(null);
    setBusy(true);
    try {
      // Called directly from the click, with no await before it.
      await signInWithPopup(getAuth(), new GoogleAuthProvider());
    } catch (err) {
      // Keep full details for debugging; show users a short message.
      console.error(err?.code, err?.message, err?.customData);
      setError(messageFor(err));
    } finally {
      setBusy(false);
    }
  }

  return (
    <div>
      <button type="button" onClick={handleClick} disabled={busy}>
        {busy ? "Signing in…" : "Continue with Google"}
      </button>
      {error && <p role="alert">{error}</p>}
    </div>
  );
}

Using signInWithRedirect instead? Redirect errors arrive when the page loads again, through getRedirectResult():

import { useEffect, useState } from "react";
import { getAuth, getRedirectResult } from "firebase/auth";
import { messageFor } from "./GoogleSignInButton";

export function useRedirectError() {
  const [error, setError] = useState(null);
  useEffect(() => {
    getRedirectResult(getAuth()).catch((err) => setError(messageFor(err)));
  }, []);
  return error;
}

How to confirm your error handling works

  1. auth/popup-closed-by-user: open the popup and close it. No message should appear and the button should come back.
  2. auth/cancelled-popup-request: double-click the button. The second click should do nothing, because the button is disabled.
  3. auth/unauthorized-domain: in a test project, open the app on a hostname that isn't in Authorized domains (for example a new preview URL). You should see your "isn't set up" message, and the console should log the code.
  4. Check that the code appears in your logs. Don't rely on error.message: with the default error map it's only a short Firebase: Error (auth/...) string.

FAQ

Where is the official list of Firebase Auth error codes?

The AuthErrorCodes entry in the Firebase JavaScript API reference for @firebase/auth lists every code the web SDK can return. The readable messages are in the SDK's source, in packages/auth/src/core/errors.ts, and are only shown in error.message if you use debugErrorMap.

Why doesn't `AuthErrorCodes.UNAUTHORIZED_DOMAIN` catch `auth/unauthorized-domain`?

In the SDK, UNAUTHORIZED_DOMAIN maps to "auth/unauthorized-continue-uri". The "auth/unauthorized-domain" code is under AuthErrorCodes.INVALID_ORIGIN. Compare against the string "auth/unauthorized-domain" to avoid the mix-up.

Why is `error.message` so short?

Firebase's reference says prodErrorMap, which leaves out the long messages, is the default error map. The detailed text is only included if you pass errorMap: debugErrorMap to initializeAuth(). The code property is the same either way, so build your logic and user messages on error.code.

Should I show `auth/popup-closed-by-user` as an error?

Usually not. It means the user closed the popup before finishing, so treat it like a cancel and reset the button.

How do I handle `auth/account-exists-with-different-credential`?

Firebase's Google sign-in guide says this happens when "One account per email address" is on and the email already belongs to another provider. Sign the user in with that provider first, then link the Google credential you got from GoogleAuthProvider.credentialFromError(error).

Sources

  1. @firebase/auth: AuthErrorCodes (Firebase JavaScript API reference)
  2. AuthErrorMap interface (Firebase JavaScript API reference)
  3. firebase-js-sdk: packages/auth/src/core/errors.ts (GitHub)
  4. Authenticate Using Google with JavaScript (Firebase)
  5. Authenticate with Firebase Using Email Link in JavaScript (Firebase), authorized domains steps
  6. Window: open() method (MDN)
  7. Env Variables and Modes (Vite)
  8. How to use environment variables in Next.js

How this page was made: drafted with AI from the sources listed, reviewed by Pewterkit. Docs checked Oct 27, 2026. Spotted something out of date? Tell us.

Related guides