← n8n Production Guides

GUIDE · Credentials

n8n Google OAuth Token Expires Every 7 Days: The Permanent Fix

2026-10-23 · William Ayad · 9 min read

If your Gmail, Google Sheets or Google Drive credential in n8n works perfectly for about a week and then dies with invalid_grant, the cause is almost always the same, and it is not inside n8n: your OAuth app in Google Cloud Console is still in Testing mode, and Google revokes refresh tokens from Testing-mode apps after exactly 7 days. The permanent fix takes four clicks in the consent screen — set the Publishing status to Production — and you will never re-authenticate again. Below: the exact steps, the second trap that breaks self-hosters (the localhost redirect), and the expiry table for every other provider whose tokens die on their own schedule.

First, understand what is actually dying

Two different tokens live inside every OAuth credential. The access token is the short-lived key n8n actually uses to call the API — it expires after roughly an hour and that is normal. The refresh token is the long-lived secret n8n uses to mint new access tokens without asking you. When you see a weekly breakage, the refresh token is what died. n8n never warns you beforehand — as countless community threads confirm, the first symptom is a workflow that failed at 03:00 with a 401, three days after you checked everything and found it "connected". Connected means the object exists. It says nothing about whether the token inside it is still alive.

The 7-day root cause — and the 4-step permanent fix

Google assumes a Testing-mode OAuth app is unfinished. To protect users from abandoned projects, it revokes every refresh token such an app issues after 7 days — no mail, no banner, just invalid_grant. n8n cannot override a provider policy; the fix lives entirely in Google Cloud Console:

  1. Open Google Cloud Console → APIs & Services → OAuth consent screen (the project your n8n credential uses).
  2. Find the Publishing status at the top — it says Testing.
  3. Click Publish app and confirm. For personal automations Google does not require the full verification audit — status flips to Production immediately.
  4. Back in n8n, open the credential and press Reconnect once. You will pass one "Google has not verified this app" warning — click Advanced → Go to your app.

That single reconnect mints a fresh refresh token under Production status, and revocation stops. Every workflow referencing the credential keeps working — the object and its node bindings are untouched. This is the fix behind the most-repeated n8n credential complaint of 2025–26, and it is documented as "publish the consent screen" in virtually every one of those threads.

While you are in the credential: force a real refresh token

If a Google credential was created without offline access, no refresh token was issued at all and expiry arrives hourly instead of weekly. In the n8n credential, add to Auth URI Query Parameters: access_type=offline&prompt=consent, then reconnect. The prompt=consent matters: without it Google may silently skip returning a new refresh token for an already-authorized account — a half-fix that fails again next week.

The second trap: redirect_uri_mismatch on self-hosted instances

Roughly a third of credential threads are not expiry at all — they are Google rejecting the handshake up front with redirect_uri_mismatch. Google accepts byte-exact redirect URIs only. On self-hosted n8n, the OAuth Redirect URL shown in the credential dialog is built from your instance URL — and if n8n still believes it lives on localhost:5678, Google rejects a callback it never registered. Same localhost triangle that kills production webhooks: set your instance URL correctly (WEBHOOK_URL / host env, exact scheme and port), then copy the Redirect URL from the credential dialog into Google Cloud Console character for character — no trailing-slash creativity, no http where https lives.

It is not only Google: the provider expiry table

Google is the loudest case because its Testing mode revokes weekly, but every OAuth provider runs its own clock — and n8n will not warn you about any of them. The documented patterns that matter in production:

ProviderRefresh-token lifetimeThe trap that bites n8n users
Google (Gmail, Sheets, Drive, Calendar)7 days in Testing mode · effectively permanent in ProductionConsent screen never published; missing access_type=offline
Microsoft / Outlook / Teams~90 days rolling (consumer) · Azure AD policy for work accounts, often 14 days idleUsing .default scope — Azure issues no usable refresh token; use explicit scopes + offline_access on v2.0 endpoints
Meta / Facebook~60 days (long-lived)No renewal ritual; the quarter changes, the workflow dies
SlackStable unless token rotation is enabled on the appRotation on + reconnect forgotten = silent death
XeroExpires 60 days after last useA seasonal workflow pauses past the window

One more silent killer worth its own sentence: reconnecting too often can kill your other workflows. Google caps live refresh tokens per OAuth client ID, and the same account authorizing the same client over and over quietly revokes the oldest token. Two credential entries pointing at one client ID, or a second n8n instance sharing it, is a self-inflicted rotation attack. Consolidate to one credential per client, and reconnect that one.

When the honest answer is a Service Account

For headless Google Sheets/Drive automation there is a structural escape from the whole OAuth lifecycle: a Google Service Account. Server-to-server JWT credentials do not expire, need no consent screen, and never touch a user's refresh-token budget. The pattern: create the service account in Google Cloud, share the target Sheet/Drive folder with its email address, and use the service account credential type in n8n. Limits to respect: it acts as a robot user, not as you (no "send as alice@company.com" without Workspace domain-wide delegation), and Drive quota/billing attach to the project. For read-your-own-spreadsheets automations — the most common n8n use case that breaks weekly — it is the correct permanent answer.

If your error is none of the above, stop guessing in the forum

Expiring tokens are one credential failure class; providers also answer with scope rejections, revoked PATs and malformed handshake errors that surface in n8n as raw crash text — 401 Client must be authenticated, insufficient authentication scopes, connection-refused chains that are really revoked keys. Before opening yet another "weird error" thread, paste the exact error text into the free n8n Error Doctor: it pattern-matches the documented crash classes — credential rejections included — and returns the fix and its provider-level cause in about two seconds, browser-only. Two seconds of pattern match beats two days of forum latency, and if the error is genuinely new, you at least post in the community with a classified problem instead of a screenshot.

Prevention for teams: monitor the heartbeat, not the token

You cannot subscribe to an expiry warning that no provider sends. What you can do is detect the absence of success: an execution stream that goes quiet is the earliest real symptom of a dead credential — which is exactly the third layer of the 3-layer monitoring setup. Two deployment notes for the self-hosted crowd: in queue mode, DB-stored credentials are shared by main and workers (reconnect once, everywhere heals) — but credentials injected via environment variables must exist and match on every worker, or Monday's token lives only on the main process. And never store the encryption key next to the database: a rotated or lost N8N_ENCRYPTION_KEY makes every stored credential unreadable at once — the recovery checklist lives in the backup and disaster-recovery guide.

The one-paragraph answer to bookmark

Weekly expiry → publish the OAuth consent screen from Testing to Production, reconnect once with access_type=offline&prompt=consent, keep one credential per client ID, and consider a Service Account for headless Sheets/Drive. Microsoft dies on idle clocks and .default scopes; Meta and Xero die on 60-day calendars; Slack dies when rotation is on and nobody reconnects. All of it is invisible until the first failed execution — so the last fix is not a Google setting at all, but a monitor that notices silence before your users do.

The fixes that do not work (stop doing these)

Half of the advice recycled in credential threads treats the symptom and quietly guarantees next week's failure. Three patterns to retire:

Reconnecting on a schedule. A calendar reminder to re-authorize every Sunday is a maintenance job you invented for yourself — and each extra authorization burns one slot of Google's live refresh-token budget for that account, so the ritual itself becomes the revoker. Publishing the consent screen removes the need for any ritual.

Deleting and recreating the credential every time. A fresh credential object forces you to re-point every node that referenced the old one; miss one node and the workflow fails differently next week. Reconnect in place — the object survives, the bindings survive, only the token rotates.

"Just switch to an API key." Google's user-context APIs (Gmail, Calendar, personal Drive) do not accept plain API keys — they only exist for a subset of public-data endpoints. For anything that acts as a user, OAuth or a Service Account with delegation are the two real doors. Where a provider genuinely offers a PAT model (Airtable, GitHub), the calculus reverses: a PAT with a storage-and-rotation routine is simpler than OAuth, and its failure mode is revocation, not expiry — the same class of failure the error-codes map covers under authentication entries.

Verify the fix actually held — the 8-day test

A reconnect proves the handshake works today; it proves nothing about next week. The confirmation protocol is cheap and runs itself: keep any small Google-connected workflow on a daily schedule (a Sheet read is enough), and check its executions on day 8 and day 15. Successes on both dates are the empirical proof the refresh token survived past the Testing-mode horizon — the failure you removed had a strict 7-day signature, so outliving it twice is conclusive. If the workflow instead dies again exactly on schedule, the consent screen flip did not stick (wrong project, or the credential still points at a different client ID than the one you published) — revisit the project selector in Cloud Console before anything else.

Frequently asked questions

Why do my n8n Google credentials expire every 7 days?

Because the OAuth consent screen of your Google Cloud project is in Testing mode — Google revokes its refresh tokens after 7 days by design. Set the consent screen Publishing status to Production and reconnect once; the revocation stops permanently.

Do I need Google app verification to stop the 7-day expiry?

No. Publishing to Production is enough for personal and internal automations — you click through one "unverified app" warning when reconnecting. Full verification is only for OAuth apps shipped to external users at scale.

Will reconnecting the credential break my running workflows?

No — the credential object and its node bindings survive; only the token rotates. The hazard is creating duplicate credentials per client ID: Google's live refresh-token cap silently revokes the oldest token and takes down a different workflow. One credential per client, reconnect in place.

Does n8n warn me before a token expires?

No. n8n learns of the death at the next 401 from the provider — the first "warning" is a failed execution. Monitor for the absence of successful runs instead of waiting for an alert that never comes.

Where the free tool stops (honesty first)

The Error Doctor classifies crash text — including the credential classes above — from patterns documented in the field; it does not hold your OAuth secrets and cannot renew a token for you (nothing outside Google can). The full failure-bank entries behind these classes — provider-by-provider rebuild checklists, the preflight rules that catch credential-risk patterns before production, and the incidence-ranked error library — live in the n8n Reliability Kit, one-time $19 launch (disclosing: mine), browser-local like the free tools.