Common Google OAuth & Gmail API Errors (and How to Fix Each One)
Every developer integrating Gmail or Google Calendar with Google OAuth will hit at least one of these google oauth errors. This guide consolidates all 7 common Google OAuth errors in one place - with the exact cause and the step-by-step fix for each one. Understanding these google oauth errors will save hours of debugging.
# Google OAuth token exchange
import requests
token_response = requests.post(
"https://oauth2.googleapis.com/token",
data={
"code": authorization_code,
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"redirect_uri": REDIRECT_URI,
"grant_type": "authorization_code"
}
)Quick reference: every Google OAuth error at a glance
A single-table summary of all 7 google oauth errors covered in this guide - stage where it occurs, root cause, and the quick fix link to the detailed section below. Bookmark this table as a reference when debugging google oauth errors in development or production.
| Error message | Stage | Root cause | Quick fix |
|---|---|---|---|
| redirect_uri_mismatch | Authorization | The redirect URI in your request does not exactly match one registered in Google Cloud Console | Fix it |
| admin_policy_enforced | Authorization | A Workspace super admin has restricted which OAuth apps or scopes users in the org can grant access to | Fix it |
| access_denied | Authorization | App is in Testing mode and the user is not a test user, or app requests restricted scopes without verification | Fix it |
| invalid_grant | Token refresh | Refresh token expired, revoked, or used more than once (single-use auth code) | Fix it |
| Consent screen missing | Google Cloud Console | New Google Cloud UI moved OAuth consent screen; also requires Owner/Editor role on the project | Fix it |
| invalid_scope | Authorization | Scope URL typo or the corresponding Google API is not enabled in the project | Fix it |
| Google hasn't verified | Authorization | App uses sensitive/restricted scopes but has not completed Google verification; Testing mode caps at 100 users | Fix it |
Error 400: redirect_uri_mismatch
This is the most common Google OAuth error for developers setting up a new integration. It fires during the authorization step - before any token is issued.
The exact error message
Error 400: redirect_uri_mismatch
The redirect URI in the request did not match a registered redirect URI.
error=redirect_uri_mismatch
Cause
Google compares the redirect_uri parameter you pass in your authorization URL with the list of Authorized redirect URIs registered in your OAuth client in Google Cloud Console. Even a single character difference - a trailing slash, http vs https, or a different port - triggers this error.
Fix (step by step)
https://yourapp.com/oauth/callback. The value must be character-for-character identical, including scheme, port, and trailing slash.
redirect_uri value you pass to the authorization endpoint and to the token exchange endpoint are identical.
redirect_uri_mismatch on localhost
During local development, register the exact localhost URI you use - for example http://localhost:3000/callback. Google allows http:// (not just https://) for localhost URIs. If you change your dev port, remember to update the registered URI.
These are two separate fields and they serve different purposes. Authorized JavaScript origins are used for browser-side OAuth flows (implicit flow, Google Identity Services). Authorized redirect URIs are used for server-side authorization code flows. Adding a URI to JavaScript origins will NOT fix a redirect_uri_mismatch error - you must add it to the redirect URIs field. A Google OAuth client can have up to 100 redirect URIs registered.
Error 400: admin_policy_enforced
This error is not a bug in your code. It is an organizational policy enforced by a Google Workspace super administrator. A regular developer cannot fix it alone.
The exact error message
Error 400: admin_policy_enforced
Google Account is unable to be used for authorization because of your
organization's policies. Contact your admin for more info.
error=admin_policy_enforced
Cause
A Google Workspace super admin has restricted which third-party applications or OAuth scopes users in the organization can grant access to. This is configured via API Controls in the Google Admin Console. When an app is not on the approved list, every user in that Workspace will receive this error when they attempt to authorize it - regardless of the app's verification status.
This is a compliance and security control, not a developer-side misconfiguration. The correct resolution is always admin-side.
Fix (admin-side only)
A user who encounters admin_policy_enforced cannot resolve it themselves. They need to contact their Google Workspace super admin and request that the specific OAuth app be marked as Trusted. If the user is the admin, they can follow the steps above. If the domain enforces a strict "Allow specific apps" policy, the app must first be explicitly added to the approved list before it can be set to Trusted.
If you are building internal tooling and want to avoid per-user OAuth consent entirely, a service account with Domain-Wide Delegation is the alternative - see our Gmail service account & DWD guide.
access_denied & "This app is blocked" (unverified app)
Users see a "This app is blocked" screen or receive access_denied in the OAuth callback. This one has multiple root causes depending on whether your app is still in Testing mode or targeting restricted scopes.
The exact error message
Access blocked: [Your App Name] has not completed the Google verification process
error=access_denied
-- or --
This app is blocked.
This app tried to access sensitive info in your Google Account.
Contact the developer for more info.
Causes
While your OAuth app is in "Testing" publishing status, only users explicitly added as test users can authorize it. Anyone else gets access_denied immediately.
Testing mode is limited to 100 unique test users at any time. Once you hit 100, new users cannot authorize the app even if added.
Scopes like gmail.modify or gmail.send are Sensitive scopes. Apps requesting them must complete Google's app verification process before real users can grant access.
A small number of scopes (e.g. full Gmail access) are Restricted and require a third-party security audit (CASA) in addition to verification.
Fix
invalid_grant: "reconnect your Gmail account"
The gmail api invalid grant error is one of the most confusing in production - it breaks silently for a subset of users and requires a new OAuth flow to recover. Understanding the refresh token lifecycle is the key to handling it properly.
The exact error message
{"error": "invalid_grant", "error_description": "Token has been expired or revoked."}
-- or --
{"error": "invalid_grant", "error_description": "Bad Request"}
Cause: the refresh token lifecycle
Fix: re-authorize with access_type=offline + prompt=consent
from google_auth_oauthlib.flow import Flow
flow = Flow.from_client_secrets_file(
'client_secrets.json',
scopes=['https://www.googleapis.com/auth/gmail.readonly'],
redirect_uri=REDIRECT_URI
)
# access_type=offline → get a refresh token
# prompt=consent → force re-consent, always returns a new refresh token
auth_url, state = flow.authorization_url(
access_type='offline',
prompt='consent'
)
# Store the NEW refresh_token from the response
# old token is now invalid -- update your DBTo avoid invalid_grant in production: always use access_type=offline and prompt=consent when initiating the OAuth flow, update your stored refresh token every time the user re-authorizes, detect invalid_grant errors and trigger a graceful re-authorization UI (a "reconnect your Gmail account" prompt), and move your app out of Testing mode to get permanent tokens.
The OAuth consent screen won't show in Google Cloud Console
This is the highest-volume search query in this cluster (390+ monthly searches). The "OAuth consent screen" page appears to have disappeared from Google Cloud Console for many developers in 2024-2026 due to a UI redesign. It has not been removed - it moved.
Symptom
You open Google Cloud Console and navigate to APIs & Services, but the "OAuth consent screen" menu item is either missing or clicking it redirects you to a new "OAuth Overview" page that shows a summary dashboard instead of the configuration form you expected.
Causes
Fix (step by step)
https://console.cloud.google.com/apis/credentials/consent?project=YOUR_PROJECT_ID. This deep link bypasses the overview page and goes straight to the consent screen configuration. For a full walkthrough of every configuration field, user type selection, and the 100-user testing cap, see our OAuth consent screen setup guide.
Weeks of verification.
Use Unipile's key and start now.
Don't lose customers waiting on Google's review. Connect Gmail accounts in 5 minutes with our pre-verified developer credentials.
invalid_scope
A typo in the scope URL or a disabled API will cause Google to reject the entire authorization request before any user interaction happens.
The exact error message
{"error": "invalid_scope",
"error_description": "Some requested scopes were invalid.
{valid=[https://mail.google.com/], invalid=[gmail.readonly]}"}
-- or on the consent screen URL --
error=invalid_scope&error_description=Some+requested+scopes+were+invalid
Cause
Two common root causes: (1) the scope value is a short name like gmail.readonly instead of the full URL https://www.googleapis.com/auth/gmail.readonly, or (2) the Gmail API (or any other Google API you are scoping to) is not enabled in the Google Cloud project.
Common Gmail scopes and their correct URLs
| Scope URL (use the full URL) | What it allows | Type |
|---|---|---|
| https://www.googleapis.com/auth/gmail.readonly | Read all messages and threads | Sensitive |
| https://www.googleapis.com/auth/gmail.send | Send email on behalf of the user | Sensitive |
| https://www.googleapis.com/auth/gmail.modify | Read, compose, send, delete threads | Sensitive |
| https://mail.google.com/ | Full mailbox access (IMAP/SMTP) | Restricted |
| https://www.googleapis.com/auth/userinfo.email | Read user's email address only | Basic |
Fix
https://www.googleapis.com/auth/ or https://mail.google.com/). Never use the short form like gmail.readonly.
"Google hasn't verified this app" & the 100-user cap
The warning screen "Google hasn't verified this app" appears when an unverified app requests sensitive or restricted scopes. While users can proceed by clicking "Advanced" and then "Go to [app name] (unsafe)", this is not suitable for production - and Testing mode caps your app at 100 unique users total.
Cause
When your app requests Sensitive scopes (like gmail.readonly or gmail.send), Google displays this warning screen to every user until you complete the verification review. For Restricted scopes, you also need to pass a third-party security audit (CASA Tier 2).
While in Testing publishing status, this warning screen is also displayed even for test users, and the total number of test users allowed is capped at 100. Tokens for test users expire after 7 days.
Fix
https://mail.google.com/): additionally complete a CASA Tier 2 security assessment by a Google-approved assessor.
These errors disappear when the OAuth project is already certified
The "Google hasn't verified this app" screen, the 100-user cap, and the 7-day token expiry in Testing mode are all symptoms of owning and managing your own Google Cloud project. An independent technical intermediary that acts on behalf of each authenticated user - and has already completed CASA Tier 2 certification - removes this entire overhead from your side. Your users authorize once; token lifecycle, scope compliance, and re-verification are handled at the platform level.
This is not a workaround for Google's security review. Unipile has independently completed CASA Tier 2 and is not affiliated with, endorsed by, or sponsored by Google.
Ship on already-certified Google OAuthHow to avoid this entire class of Google OAuth errors
Looking across all 7 google oauth errors in this guide, a pattern emerges. Every single one originates from the same root: managing your own Google Cloud project and its OAuth configuration manually. These google oauth errors are not random - they are structural consequences of owning an unverified OAuth project, from redirect URI mismatches and token rotation failures to the 100-user cap and consent screen rejections.
There is another way. Using an independent technical intermediary that acts on behalf of each authenticated user - one that has already completed Google's verification review and CASA Tier 2 security certification - shifts every one of these failure modes off your plate. The comparison below shows exactly which errors disappear and which infrastructure Unipile handles instead. See the Unipile Google OAuth documentation for the full integration guide.
Every error in this guide: who owns the fix?
The 7 Google OAuth errors covered above share a common root: you own the Google Cloud project, so you own every failure mode. Here is a side-by-side look at what that means in practice.
The key distinction: Unipile has already completed Google's security review and CASA Tier 2 assessment for the connections it brokers on your behalf. This is not a workaround for Google's security review - Unipile has already passed it. Your users get a clean consent screen (no "unverified app" warning), your app ships immediately, and you can pursue your own Google Cloud verification in parallel without any production deadline pressure.
Compliance note: Unipile is an independent technical intermediary, not affiliated with, endorsed by, or sponsored by Google. Unipile's Google OAuth client is CASA Tier 2 certified, enabling your users to authorize Gmail access without an "unverified app" warning for connections brokered through Unipile. This is not a workaround for Google's security review - Unipile has already passed it for the connections it brokers on behalf of each authenticated user. Users can revoke access at any time via their Google Account permissions page.
Google OAuth errors FAQ
Answers to the most common questions about Google OAuth errors and Gmail API errors, covering token lifecycle, admin policies, redirect URIs, and Google Cloud Console configuration.
admin_policy_enforced means a Google Workspace super administrator has blocked your app or the specific OAuth scopes it requests from being authorized by users in that organization. It is an organizational access control policy, not a bug in your code. The fix requires action from the Workspace super admin in the Google Admin Console under Security > API controls > Manage Third-Party App Access.
No. A regular user cannot fix admin_policy_enforced. Only a Google Workspace super administrator can resolve this error by marking the app as Trusted in the Admin Console. The affected user needs to contact their IT administrator or Workspace super admin and request that the specific OAuth app be added to the approved list.
The redirect_uri_mismatch on localhost happens when the URI you register in Google Cloud Console does not exactly match the URI your local development server uses. For example, registering http://localhost:3000/callback but running on port 3001, or forgetting a trailing slash. Google allows http:// (not just https://) for localhost URIs. Register the exact URI your local server uses, including the correct port number.
No. Authorized JavaScript origins and Authorized redirect URIs are two separate fields. JavaScript origins are used for browser-side OAuth flows only. To fix redirect_uri_mismatch, you must add the URI to the Authorized redirect URIs field, not to JavaScript origins.
A single Google OAuth 2.0 client can have up to 100 Authorized redirect URIs registered. This allows you to register URIs for different environments (local development, staging, production) and different callback paths within the same client.
If your app is in Testing publishing status, Google refresh tokens expire after 7 days regardless of usage. This is by design for unverified apps. Move to Production status by clicking Publish App on the OAuth consent screen page to get long-lived tokens. In Production, refresh tokens remain valid as long as the user uses your app at least once every 6 months. For a managed alternative, visit our managed Gmail API solution.
Google revokes refresh tokens that have not been used for 6 months (approximately 180 days). Tokens are also revoked when: the user changes their Google account password, the user revokes app access in their Google Account security settings, you re-authorize with different scopes, or the total refresh tokens for a single user-app pair exceeds 50 (oldest get revoked first). For the full picture on building robust email integrations, see our complete Email API guide.
Google redesigned the Cloud Console in 2024. The OAuth consent screen configuration is now inside APIs & Services > OAuth overview. Click Edit App or use the Branding, Audience, and Scopes tabs. Also check: you need Editor or Owner role on the project (Viewer cannot access the form), and make sure you are on the correct project using the project selector at the top of the console.
Still hitting a Google OAuth error not listed here? Skip the debugging and let Unipile handle Gmail OAuth for you.
Build Now