n8n Google OAuth2 "invalid_grant": Why Sheets, Drive and Gmail Credentials Expire (Every 7 Days) and How to Fix It
A Google Sheets, Drive or Gmail workflow runs fine for days, then every execution fails with this:
The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
"Google Sheets OAuth2 Error" has 14,106 views on the n8n forum (Oct 31, 2026) and no accepted answer. "OAuth2 token expires every 7 days for Google Drive" (3,909 views) is the same problem from a different angle. Clicking Reconnect fixes it until the next time. This page goes through each cause Google documents, how to tell which one you have, and how to stop it coming back.
How we checked: Google's OAuth documentation, n8n's credential docs, the n8n source code (master branch, Oct 31, 2026) and the two forum threads. We have not tested these steps against a live Google account. Where a claim comes only from forum posts, we say so.
Paid option for Google Sheets users: the bulk AI runner resumes where it stopped, so a credential that dies mid-run doesn't mean starting over. It won't fix an expired token. The Pro Kit adds the Google Sheet header CSV, a 10-minute setup guide and an offline test kit (a local OpenAI, Google Sheets and Gmail mock with the 15-scenario runner), so you can watch the retries and resume work before you use a real API key. The free workflow JSON stays free.
What the error actually means
Google access tokens are short-lived, so n8n stores a refresh token and uses it to get a new access token when needed. When Google refuses the refresh token, it answers with the OAuth error code invalid_grant. n8n's OAuth library turns that code into the long sentence above, which is the generic description from the OAuth 2.0 standard (n8n source). So the message lists every possible reason. It doesn't tell you which one happened. Google's own guidance for invalid_grant on a refresh is short: the token expired or was invalidated, so authenticate the user again (Google: OAuth 2.0 for web server apps).
Reconnecting always fixes the immediate failure. Stopping it from coming back depends on the cause.
Which cause do you have?
| What you notice | Most likely cause |
|---|---|
| It breaks about 7 days after every reconnect | Cause 1: the Google Cloud app is in Testing |
| A Gmail credential broke right after you changed your Google password | Cause 2: password change with Gmail scopes |
| It broke after a security checkup, or after you removed apps from your Google Account | Cause 3: access was revoked |
| An older credential died after you connected several new ones with the same Google account | Cause 4: refresh token limit |
You can't connect at all, and Google shows redirect_uri_mismatch | Cause 5: redirect URL |
| A workflow that runs rarely fails the first time in months | Cause 6: token unused for six months |
A service account credential fails with Invalid JWT | Cause 7: server clock |
Cause 1: your Google Cloud app is in "Testing" (the 7-day expiry)
This is the one behind most "every 7 days" reports. When you create your own OAuth client for n8n and pick the External audience, Google puts the app in Testing. n8n's docs note this too (n8n: Google OAuth2 single service). Google's rule:
"A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days" (Google: Refresh token expiration)
The only exception is an app that asks for nothing but name, email and profile. n8n's Google credentials always ask for more: the Sheets credential requests spreadsheets, drive.file and drive.metadata, and the Gmail credential requests https://mail.google.com/ among others (Sheets, Gmail credential source). So a Testing app always gets 7-day tokens.
Fix: publish the app to Production.
- In Google Cloud Console, pick the project that owns the Client ID in your n8n credential. Open Google Auth Platform (APIs & Services → OAuth consent screen) → Audience.
- Under Publishing status, select Publish app and confirm. The status changes to In production (Google: Manage App Audience).
- In n8n, open the credential and reconnect (Sign in with Google), so the credential gets a refresh token issued after publishing. Google says test-user authorizations expire seven days from the time of consent, so an old token can still run out.
What to expect after publishing: Google shows an "unverified app" warning during sign-in, because Sheets' spreadsheets scope is sensitive and the full drive scope (used by n8n's Drive credential) and all Gmail read/modify scopes are restricted (Sheets scopes, Gmail scopes). For a personal automation, you are the only user, so you click past the warning. Unverified apps can be authorized by at most 100 new users over the life of the project, which doesn't matter for one person. Verification is only needed if you want other people to sign in without the warning, and restricted scopes need a heavier review.
Other ways out:
- Google Workspace: choose the Internal audience. Only users in your organization can sign in, and the Testing rules for external apps don't apply (Manage App Audience).
- n8n Cloud: for Google Sheets, Drive, Gmail and several other Google nodes, n8n Cloud offers Managed OAuth2: click Sign in with Google with no Google Cloud project of your own (n8n docs). We haven't verified how long those tokens last, but your own project's Testing status no longer applies.
- Sheets and Drive: use a service account (see below). It has no refresh token to expire.
Cause 2: you changed your Google password (Gmail credentials)
Google lists this as a reason a refresh token stops working: "The user changed passwords and the refresh token contains Gmail scopes." n8n's Gmail credential includes Gmail scopes, so a password change ends it. In t/4055, a user whose Gmail credential broke had changed their password a few days after connecting, and an n8n team member pointed to this cause. Reconnect after every password change. Google's list mentions this rule only for Gmail scopes.
Cause 3: access was revoked
A refresh token stops working when "the user has revoked your app's access" (Google). That happens if you, or a security checkup, remove the app from your Google Account's list of third-party connections. Google lists more cases on the same page:
- You granted time-based access to the app and it ran out.
- In Google Workspace, an admin set one of the requested services to Restricted. The error then is
admin_policy_enforced. - For Google Cloud Platform scopes, an admin's session length policy expired (
invalid_rapt). This applies to the Cloud Platform scope, not to Sheets, Drive or Gmail.
Reconnect. If you're on Workspace and it keeps happening, ask your admin whether the app is allowed.
Cause 4: too many refresh tokens for one Google account
Google: "There is currently a limit of 100 refresh tokens per Google Account per OAuth 2.0 client ID. If the limit is reached, creating a new refresh token automatically invalidates the oldest refresh token without warning." There's also a larger limit across all clients, which a developer's test account can hit (Google).
That matters in n8n because the Google credential signs in with access_type=offline&prompt=consent (source), so every Sign in with Google click asks for a new refresh token. Many credentials, many reconnects and several n8n instances, all with the same Google account and Client ID, add up. The oldest credential is the one that silently dies. Delete credentials you don't use, reuse one credential per Google account per instance instead of creating a new one for each workflow, and follow Google's tip to keep each Google account to about 15 to 20 authorized clients.
Cause 5: the redirect URL doesn't match
The error text mentions "does not match the redirection URI", but in practice a redirect problem stops you when you connect, with Google's redirect_uri_mismatch page. n8n's fix: copy the OAuth Redirect URL from the n8n credential panel and paste it exactly, including http/https and the port, into Authorized redirect URIs on the Google OAuth client (n8n docs).
If the URL in the panel looks wrong (for example http://localhost:5678/… on a server behind a reverse proxy), fix n8n's base URL first. In the source, n8n builds the callback as the instance base URL plus /rest/oauth2-credential/callback, and the base URL comes from N8N_EDITOR_BASE_URL, then N8N_WEBHOOK_URL (older name WEBHOOK_URL), then protocol, host and port (url.service.ts, oauth.service.ts). Set N8N_EDITOR_BASE_URL to your public URL, restart, and copy the new redirect URL into Google. If you move n8n to a new domain, add the new URL to the Google client and reconnect.
Using one OAuth client for several n8n instances
One Google OAuth client can serve several instances (dev and prod, an old and a new server), but:
- Each instance has its own redirect URL, and every one of them must be listed in the client's Authorized redirect URIs.
- Each instance's connection is a separate refresh token for the same Google account and Client ID, so they all count toward the 100-token limit in cause 4.
- The client's publishing status (cause 1) applies to all of them. One Testing app means 7-day tokens on every instance.
- If the client was deleted, Google returns a different error,
deleted_client. Google says deleted clients, including ones it removes automatically for being unused, can be restored within 30 days (Google).
Cause 6: the token wasn't used for six months
Google also expires refresh tokens that haven't been used for six months. A yearly or seasonal workflow can hit this. Reconnect before it runs, or let a small scheduled workflow use the credential once a month.
Cause 7: clock skew (service accounts only)
Google documents a clock problem as an invalid_grant cause for service accounts: "Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe… Usually, it means that the local system time is not correct" (Google: service accounts). If a service account credential fails this way on a self-hosted server, check the server's time sync (NTP). We found no Google documentation saying clock skew causes invalid_grant for a normal OAuth2 refresh token, so we don't list it as a cause for those.
The alternative for Sheets and Drive: a service account
A service account signs its own short-lived tokens with a private key, so there's no refresh token, no 7-day Testing expiry and no password tie-in, and Google says the 100-token limit doesn't apply to service accounts. n8n's setup (n8n: Google Service Account):
- In the same Google Cloud project, enable the APIs your nodes use (Google Sheets API, Google Drive API).
- APIs & Services → Credentials → Create credentials → Service account, then Keys → Add key → Create new key → JSON.
- In n8n, create a Google Service Account API credential: paste
client_emailas the Service Account Email andprivate_keyas the Private Key. - Share the spreadsheet or folder with the service account's email (Editor to write, Viewer to read). A service account can't see files that weren't shared with it.
- Switch the Google Sheets or Drive node's authentication to Service Account and pick the credential.
Caveats: n8n's docs warn that service accounts created after April 15, 2025 can't access My Drive, only shared drives, unless you use domain-wide delegation. We couldn't find that statement in Google's own documentation, so try it with one shared file before you rebuild a workflow around it. For Gmail on a personal account, a service account isn't an option: acting as a user needs domain-wide delegation set up by a Google Workspace super admin. Personal Gmail users should publish the app (cause 1). Treat the JSON key like a password.
Reconnect checklist
- Read the failed execution's error. If it's the
invalid_granttext above, the stored refresh token is dead. Retrying won't help. - In Google Cloud Console, open the project that owns the credential's Client ID. Check Audience: if it says Testing, publish it now (cause 1).
- Check that the APIs you use are enabled (Sheets, Drive, Gmail).
- Check that n8n's OAuth Redirect URL is listed exactly under the client's Authorized redirect URIs (cause 5).
- In n8n, open Credentials, open the Google credential, and click Sign in with Google. Use the same Google account as before, and approve every scope Google asks for.
- Save, then run one node that uses the credential by hand to confirm it works.
- Re-run the failed executions you need.
- Delete old duplicate credentials for the same account (cause 4).
Get alerted the moment it breaks
An expired token fails quietly unless you're watching the Executions list. n8n's error workflow fixes that (n8n: error handling):
- Create a workflow that starts with an Error Trigger node, name it
Error Handler, and save it. - Add a notification node. Don't send the alert through the same Google credential, because it's the thing that just broke. Use a different channel, such as the Send Email node with SMTP, Slack, Telegram or a different Google account.
- Message text, for example:
{{ $json.workflow.name }} failed: {{ $json.execution?.error?.message || $json.trigger?.error?.message }}. When the failing node is the trigger itself, n8n puts the details undertriggerinstead ofexecution. - In each Google workflow, open Settings → Error workflow, pick
Error Handlerand save. - Optional: add an If node that checks whether the message contains
invalid_grantorauthorization grantand sends a "reconnect the Google credential" alert with a link to your n8n credentials page.
If you have to stay in Testing for now, add a reminder too: a Schedule Trigger every 6 days that emails you to reconnect before the 7 days run out.
n8n workflow JSON: OpenAI over every row in batches, waits for Retry-After on 429, resumes where it stopped, one Sheets write per batch. No credentials inside. It won't fix an expired Google token; it makes recovering from one painless.
Want the sheet template and an offline test kit too? The Sheets Bulk AI Runner Pro Kit ($19) adds the sheet header CSV and an offline test kit (a local OpenAI, Sheets and Gmail mock). The free JSON stays free.
FAQ
Why does my n8n Google credential expire every 7 days?
Your Google Cloud OAuth app is set to the External audience with publishing status Testing. Google issues 7-day refresh tokens to such apps unless they only ask for name, email and profile, and n8n's Google credentials always ask for more. Publish the app to Production in Google Auth Platform, Audience, then reconnect the credential.
What does 'The provided authorization grant ... or refresh token is invalid, expired, revoked' mean in n8n?
It is n8n's wording for Google's invalid_grant error: Google refused the stored refresh token. The sentence lists every possible reason from the OAuth standard. Common real causes are the 7-day Testing expiry, a password change on a Gmail credential, revoked access and the 100-refresh-token limit. Reconnecting fixes it right away.
Do I need to verify my Google app to stop the 7-day expiry?
Google's documentation ties the 7-day expiry to the Testing status, not to verification. A published but unverified app shows an unverified-app warning at sign-in, which you can click past for personal use. Forum reports disagree about whether unverified production apps keep tokens past 7 days, and we have not confirmed it ourselves.
Can I use a service account instead of OAuth2 for Google Sheets in n8n?
Yes. Create a service account with a JSON key, add a Google Service Account API credential in n8n, and share the spreadsheet with the service account's email. There is no refresh token to expire. n8n's docs warn that service accounts created after April 15, 2025 can't access My Drive, only shared drives, so test with one file first. Personal Gmail can't use a service account.
How do I get notified when a Google credential breaks in n8n?
Create an error workflow that starts with an Error Trigger node and sends an alert through a different channel than the broken Google credential, such as SMTP email or Slack. Then select it under Settings, Error workflow in each Google workflow.