Problem Summary
You have built an application that requires Google OAuth. You have filled in the OAuth consent screen in Google Cloud Console, submitted for verification, and received a rejection email from Google's Trust and Safety team. The email is vague. It cites policy violations but does not point to specific fields or tell you exactly what to fix. You update what you think is wrong, resubmit, and get rejected again. This cycle repeats for weeks.
Symptoms
- Rejection email from noreply@accounts.google.com citing 'Google API Services User Data Policy' violations
- The rejection references 'inaccurate or incomplete information' without specifying which fields
- Your app is stuck in 'Testing' mode with a maximum of 100 test users
- Users see a 'Google hasn't verified this app' warning screen with a scary 'Advanced > Go to [app] (unsafe)' link
- Rejection reason mentions 'homepage URL' or 'application homepage' does not meet requirements
- Email says sensitive scopes require additional justification but the justification field is not obvious in the console
- The 'Authorized domains' section shows your domain as unverified
- Support responses reference the same policy documents without actionable guidance
Business Impact
An unverified OAuth app in Testing mode is limited to 100 test users. You can add them manually in the Google Cloud Console, but any real user who is not on the list sees the 'unverified app' warning and most will abandon the sign-in flow. This blocks any organic growth, makes the app appear untrustworthy to potential customers, and prevents you from launching publicly. For B2B apps requiring Google Workspace scopes, being stuck in Testing mode means your target enterprise customers simply cannot use the product.
Root Cause
Google divides OAuth scopes into three tiers: non-sensitive (email, profile, openid), sensitive (calendar.readonly, drive.file, gmail.send), and restricted (gmail, drive, contacts). Each tier has progressively stricter review requirements. Most rejections happen because developers do not realize that requesting even one sensitive scope triggers a full manual review with requirements for a working privacy policy URL, a real homepage that describes the app, and a verified domain. Requesting a restricted scope (full Gmail access, full Drive access) additionally requires a security assessment from an approved Google auditor a paid, months-long process.
The single most common rejection cause: requesting broader scopes than necessary. If you request https://www.googleapis.com/auth/gmail when you only need https://www.googleapis.com/auth/gmail.send, Google will reject the application. Always request the most narrowly scoped permission that covers your use case.
Diagnosis
Step 1: Audit Which Scopes You Are Requesting
Navigate to Google Cloud Console > APIs & Services > OAuth consent screen > Edit App > Scopes. Review every scope you have added. Cross-reference each one against Google's OAuth scopes reference at developers.google.com/identity/protocols/oauth2/scopes. Identify whether each scope is non-sensitive, sensitive, or restricted.
Non-sensitive scopes (openid, email, profile, userinfo.email, userinfo.profile) do not require verification for public apps. If you only need to identify users, use these and remove everything else. Your app will be verified automatically and show a standard consent screen without warnings.
Step 2: Verify Your Authorized Domain
In the OAuth consent screen configuration, the 'Authorized domains' field must match the domain of your application homepage and privacy policy URL. The domain must be verified in Google Search Console. An authorized domain that is not Search Console-verified will cause automatic rejection.
# Verify domain ownership via Google Search Console
# 1. Go to search.google.com/search-console
# 2. Add your domain (e.g. example.com)
# 3. Complete DNS TXT record verification
# 4. Once verified, return to Cloud Console the authorized domain will show as verifiedStep 3: Check Privacy Policy Requirements
Google requires a privacy policy URL that is publicly accessible (no login required), on the verified domain, and contains specific content. A link to a generic template or a placeholder page will cause rejection. The privacy policy must explicitly address: what user data you collect via Google OAuth, how you use it, how users can request deletion, and that you do not sell data.
# Privacy Policy Required Content for Google OAuth Verification
## What we collect via Google APIs
- Specific scopes requested and what data they access
- Example: "We access your Gmail send scope to send emails on your behalf"
## How we use the data
- Specific use cases, not vague statements like "to improve your experience"
## Data retention
- How long you store tokens and user data
- What happens to data when a user disconnects your app
## User rights
- How users can revoke access (link to myaccount.google.com/permissions)
- How users can request deletion of their data
## Data sharing
- Explicit statement that you do not sell or share data with third parties
- List any third-party services that receive the data (analytics, error tracking)Step 4: Ensure the Application Homepage Is Real
The 'Application home page' URL in the OAuth consent screen must lead to a real, publicly accessible page that describes what your application does. Google's reviewers visit this page. A landing page under construction, a redirect to a login wall, or a blank page is an automatic rejection. The page must describe the product, its purpose, and ideally reference the Google API integration and the data it uses.
Step 5: Add Test Users During Development
While your app is in Testing mode, only manually approved Google accounts can complete the OAuth flow without seeing warnings. Add all developer and tester email addresses under OAuth consent screen > Test users. This allows you to verify the complete OAuth flow works correctly before submitting for production verification.
# List current OAuth client config (requires gcloud CLI)
gcloud auth application-default login
# You cannot add test users via CLI must use the Console UI:
# Cloud Console > APIs & Services > OAuth consent screen > Test users > Add users
# Add each email that needs to test the OAuth flow during reviewProduction Failure Scenarios
Scenario 1: Restricted Scope Requested Without Security Assessment
A developer requests https://www.googleapis.com/auth/drive (full Drive access) because the app needs to read one specific folder. Google places the app in a restricted scope review queue that requires a CASA Tier 2 security assessment from an approved vendor. The assessment costs thousands of dollars and takes months. Fix: use https://www.googleapis.com/auth/drive.file instead, which only grants access to files the app creates or explicitly opens, and qualifies for the standard sensitive scope review.
Scenario 2: Privacy Policy URL Returns 404 During Review
The privacy policy URL was set to /privacy-policy in a Next.js app deployed to Vercel. During a redeployment, a routing change made the page return 404. Google's reviewer attempted to access the URL days after submission and received an error. The application was rejected. Fix: use an absolute URL (https://example.com/privacy-policy), test it from an incognito window before every submission, and set up uptime monitoring on the privacy policy page.
Scenario 3: OAuth Client ID/Secret Rotated Mid-Review
During the weeks-long review period, a developer rotated the OAuth client credentials for security reasons. Google's review was still tied to the original client ID. The app appeared to work for test users but the reviewers' testing environment used the new client and could not complete the OAuth flow. Avoid rotating OAuth credentials while a review is in progress.
Prevention Checklist
- Request the minimum necessary Google OAuth scopes audit each scope against your actual feature requirements
- Verify your domain in Google Search Console before submitting the OAuth consent screen
- Publish a complete, publicly accessible privacy policy that explicitly addresses Google API data handling
- Ensure the application homepage describes the product and is accessible without login
- Add all developers and QA testers to the Test users list before the app goes live
- Do not rotate OAuth credentials while a review is pending
- For sensitive scopes, prepare a clear 'justification' in the OAuth consent screen explaining exactly why each scope is needed and how the data is used
- Test the entire OAuth flow from an incognito window using a non-test-user Google account before submitting to catch the 'unverified app' warning experience
- Keep a dedicated staging OAuth client for development never test against the production client ID
- Set up monitoring on your privacy policy and homepage URLs to catch 404s before review
Resolution Summary
The repeated rejections were caused by three issues: the privacy policy lacked explicit Google API data handling language, the authorized domain was not verified in Google Search Console, and the application was requesting https://www.googleapis.com/auth/gmail when https://www.googleapis.com/auth/gmail.send was sufficient. After narrowing the scope, verifying the domain, and updating the privacy policy with explicit Google API sections, the app passed verification on the next submission.
Lessons Learned
- Google's rejection emails are intentionally vague treat each one as requiring a comprehensive audit of all consent screen fields, not just the one they mention
- Scope reduction is almost always the fastest path to approval spend time finding the narrowest scope that meets your needs
- Domain verification in Search Console is a hard prerequisite that the Cloud Console UI does not enforce at submission time but Google's reviewers check
- Build the privacy policy page before the OAuth integration, not after it is a blocking requirement, not an afterthought
- Keep a detailed changelog of every submission and rejection to avoid re-introducing rejected configurations
Conclusion
Google OAuth verification is a process that rewards preparation over speed. Most rejections are repeat rejections of the same underlying issues: overly broad scopes, incomplete privacy policy, unverified domain. Fix all three systematically before resubmitting and you typically pass on the next attempt. Rushing resubmissions without addressing the root cause wastes the review queue time and delays your launch further.