# Google sign-in fails for some users

> Google sign-in works for you but not for others. Usually the consent screen is in Testing or Internal mode, users are in an in-app browser, the callback URL changed, or a sign-up trigger fails.

Source: https://supahost.app/kb/google-auth-fails · Updated 2026-11-11

## What you see

You and a few teammates can sign in with Google, but other users can't. They see a Google error page such as:

```
Error 403: access_denied
Error 403: org_internal
Error 403: disallowed_useragent
Error 400: redirect_uri_mismatch
```

Or they get through Google and come back to your app with `error_description=Database+error+saving+new+user` in the URL.

## Why it happens

Most of these errors come from Google's side, before Auth is involved:

| Error or symptom | Cause |
|---|---|
| `access_denied`, "has not completed the Google verification process" | The OAuth consent screen is in **Testing**, which only allows the test users you listed. |
| `org_internal` | The app's user type is **Internal**, so only accounts in your Google Workspace organisation can sign in. |
| `disallowed_useragent` | The user opened your site inside an app's built-in browser (Instagram, Facebook, LinkedIn and others). Google blocks sign-in in embedded web views. |
| `redirect_uri_mismatch` | The project's callback URL isn't in the client's **Authorized redirect URIs**, often after a custom domain was added. |
| Back in your app with "Database error saving new user" | Google worked, but creating the new user failed, usually a trigger on `auth.users`. Existing users are unaffected, which is why it looks random. |

## How to fix it

1. **Publish the consent screen.** In Google Cloud console, open the OAuth consent screen (Google Auth Platform → **Audience**), set the publishing status to **In production**, and set the user type to **External** unless you really want Workspace-only sign-in. The basic `openid`, `email` and `profile` scopes don't need Google's sensitive-scope review.

2. **Check the redirect URI.** In the OAuth client's **Authorized redirect URIs**, add your project's callback exactly:

   ```
   https://app-one.acme.supahost.space/auth/v1/callback
   ```

   If the project has an active custom domain, add the callback on that domain as well, for example `https://api.invoices.example/auth/v1/callback`.

3. **Handle in-app browsers.** Detect common embedded browsers and ask the user to open the page in their normal browser. In native mobile apps, use the system browser for OAuth, or Google's native sign-in with `supabase.auth.signInWithIdToken({ provider: "google", token })`.

4. **Fix new-user failures.** If only first-time users fail, test your sign-up trigger. See [Database error saving new user](/kb/database-error-saving-new-user).

5. **Read the error your app received.** Auth passes provider errors back to your redirect URL. Log them on your callback page so you can see what users hit:

   ```ts
   const url = new URL(window.location.href);
   const hash = new URLSearchParams(url.hash.slice(1));
   const err = url.searchParams.get("error_description") ?? hash.get("error_description");
   if (err) console.warn("Google sign-in failed:", err);
   ```

## On SupaHost

- Google is configured under Dashboard → your project → **Auth** tab → **OAuth providers** → Google. The client secret is stored in Vault and never shown again; leave the field empty to keep the stored one.
- The callback URL shown there uses your project host, or the oldest active custom domain once one is live. When you add a domain, update Google before users notice. See [OAuth broke after adding a custom domain](/kb/oauth-after-custom-domain).
- Auth settings are per project, and a branch doesn't copy them. Configure Google on each project and branch that needs it.

## Related

- [Sign in with Google](/docs/auth/google)
- [OAuth broke after adding a custom domain](/kb/oauth-after-custom-domain)
- [Database error saving new user](/kb/database-error-saving-new-user)
- [Every OAuth provider: setup reference](/docs/auth/oauth-providers)
