Skip to content
Skip to main content

Fix Google access_denied OAuth errors

Last updated:

Your user clicks Connect, signs in to their Gmail or Google Workspace account, and instead of returning a grant, Google stops them with an “access blocked” page or a warning that “Google hasn’t verified this app.” No code reaches your callback, and the user can’t finish connecting. This is the most common Google OAuth blocker, and it almost always traces to your Google Cloud app’s publishing state, not to a bug in your code.

Google returns access_denied at the token layer when the user can’t consent to your app. It surfaces during sign-in as either the red “Access blocked” screen or the yellow “Google hasn’t verified this app” warning. This page maps each cause to its fix. For the full review workflow, see the Google verification and security assessment guide.

Why does the Google access_denied error happen?

Section titled “Why does the Google access_denied error happen?”

The access_denied error happens because Google won’t let a user consent to an app it hasn’t approved for the scopes you requested. When your app is unverified or stuck in Testing mode, Google blocks anyone who isn’t on the test-user list. Google caps unverified external apps at 100 authenticated accounts until you pass review.

Four conditions trigger it. Your OAuth app is in Testing mode and the user isn’t one of the 100 allowed test users. Your app is In production but hasn’t passed Google verification, so external users see the unverified warning. You requested a restricted scope like gmail.readonly that needs both verification and a security assessment. Or the user clicked Cancel on the consent screen, which also returns access_denied.

Fix access_denied while your app is in Testing mode

Section titled “Fix access_denied while your app is in Testing mode”

While your Google Cloud app is in Testing mode, only accounts on the test-user list can connect, and everyone else gets access_denied. Add the user’s email as a test user on the OAuth consent screen and they can connect within seconds, no review required. Testing mode supports up to 100 test users, which covers most development and demo work.

Add test users in the Google Cloud Console under APIs & Services > OAuth consent screen > Test users. This is the fastest unblock during development because it skips Google review entirely. Apps set to “Testing” are an explicit exception to verification, alongside internal-only apps and apps that access fewer than 100 Gmail accounts. Don’t ship a Testing-mode app to real users, though: the 100-account ceiling and the 7-day refresh-token expiry on unpublished apps will break production sync.

Fix the “Google hasn’t verified this app” warning

Section titled “Fix the “Google hasn’t verified this app” warning”

In production, an unverified external app shows the “Google hasn’t verified this app” warning, and users who don’t click through to Advanced > Go to (app) (unsafe) trigger access_denied. Google limits these unverified apps to 100 authenticated accounts. The only way to remove the warning for all users is to complete Google’s OAuth verification.

Submit your app for verification from the OAuth consent screen once it’s set to In production. Verification reviews your branding, scopes, and a demo of the consent flow, and Google’s docs note the process can take several weeks. To pass faster, request only the scopes your features use, since every sensitive or restricted scope adds review time. The verification and security assessment guide walks through the full submission, and creating a Google auth app covers the external-versus-internal choice that decides whether you need it at all.

Fix access_denied caused by restricted scopes

Section titled “Fix access_denied caused by restricted scopes”

Restricted scopes are the highest-privilege Gmail permissions, and an app requesting them stays blocked with access_denied for external users until it clears both verification and a security assessment. Nylas uses three restricted Gmail scopes: gmail.readonly, gmail.modify, and gmail.compose. Each one requires a CASA security assessment that Google assigns at Tier 2 or Tier 3.

Request the narrowest scope that does the job. Sending mail only needs the sensitive gmail.send scope, which skips the security assessment entirely, while reading the full mailbox needs the restricted gmail.readonly scope. Trimming an unused restricted scope can drop your app from the assessment track to the lighter verification-only track. The granular scopes reference lists the exact scope strings per provider and which ones are restricted, so you can audit your connector before submitting.

What scope tiers trigger Google OAuth verification?

Section titled “What scope tiers trigger Google OAuth verification?”

Google sorts every OAuth scope into three tiers, and the highest tier you request decides how much review your app faces. The 3 baseline non-sensitive sign-in scopes (openid, userinfo.email, and userinfo.profile) trigger no verification. Sensitive scopes trigger brand verification. Restricted scopes trigger brand verification plus an annual CASA security assessment.

The tier sets the cost of going live. An app that requests only non-sensitive scopes ships without review, so the bare sign-in flow never sees access_denied from a verification gate. The moment you add a sensitive Gmail or Calendar scope, Google requires brand verification of your OAuth consent screen: a configured app homepage, a published privacy policy, a verified authorized domain, and a “Sign in with Google” button that meets the branding guidelines. Restricted scopes add the heaviest gate. Per Google’s policy, apps using them need “an annual security assessment from a Google empanelled group of security assessors,” assigned at CASA Tier 2 or Tier 3. The assessment recurs every 12 months, so it’s an ongoing cost, not a one-time gate. Nylas treats gmail.send as the escape hatch here: it sends mail under the sensitive tier and skips the assessment, so a send-only integration clears review far faster than one that reads the inbox. The verification guide’s scope table marks exactly which of the 12 Nylas Google scopes need verification, an assessment, or neither.

How long does Google OAuth verification take, and what do users see?

Section titled “How long does Google OAuth verification take, and what do users see?”

Google OAuth verification runs in two stages with very different timelines. Brand verification of a sensitive-scope app typically clears in a few days. Restricted-scope verification adds the CASA security assessment, which Google’s own docs warn “can take several weeks or longer.” Plan your launch around the longer path if you read Gmail.

The state of your review decides exactly what the user hits during sign-in. While the app sits unverified in production, external users see the yellow “Google hasn’t verified this app” interstitial and must expand Advanced > Go to (app) (unsafe) to continue; anyone who backs out returns access_denied. An app still in Testing shows no warning to the up-to-100 listed test users, but blocks everyone else outright with the red “Access blocked” screen. Once verification passes, the warning disappears for all users and the consent screen renders clean. A practical caveat on the Testing path: Google issues external Testing-mode apps a refresh token that expires in 7 days, so a grant that authenticates fine on Monday stops syncing the following week. That 7-day clock is the single most common reason a Testing-mode demo “works, then breaks.” Don’t rely on it for anything past a short demo. The verification and security assessment guide covers the submission itself, including the demo video Google requires for sensitive and restricted scopes.

How do I prevent the access_denied error before launch?

Section titled “How do I prevent the access_denied error before launch?”

Prevent access_denied by clearing verification before you expose the app to real users, not after the first support ticket. Three moves cover almost every case: request the narrowest scopes your features actually use, set the app to In production and pass review before you exceed 100 users on the unverified cap, and configure the OAuth consent screen completely so brand verification has nothing to flag.

Scope discipline does the most work here. Every restricted scope you drop removes an entire CASA assessment from your critical path, and an app that only sends mail never touches the assessment track at all. Configure the consent screen in full before submitting: a missing privacy-policy URL or an unverified authorized domain is a common reason Google bounces a brand review and resets your timeline. Keep separate Google Cloud apps for test and production, since even small edits to a verified app can trigger a fresh review. You can also sidestep most of this work entirely. A Nylas-hosted connector lets your users authenticate through a pre-verified Google app, so you inherit that completed verification instead of running your own. The trade-off is that the consent screen then shows “Nylas” rather than your brand, which buys you a skip past the multi-week review.

Google access_denied has 4 common triggers, and matching the right one saves hours of guessing. Each row maps a symptom to its cause and the concrete fix. The access_denied string is the literal error Google returns at the token layer, so you can grep your auth logs for it to confirm the diagnosis before acting.

SymptomCauseFix
access_denied, user not on test listApp is in Testing modeAdd the user as a test user (up to 100), or publish and verify the app
”Google hasn’t verified this app” warningApp In production but not yet verifiedComplete Google verification
access_denied only on Gmail read or modifyApp requests a restricted scope without a security assessmentPass verification plus the CASA assessment, or drop to gmail.send
access_denied right after the consent screenUser clicked Cancel or denied a scopeRe-run the flow and have the user approve every requested permission