LeadPulse
Blog

n8n Google Credentials Expired Overnight? Why OAuth Tokens and Service Accounts Break, and How to Catch It

31 Oct 2026

A workflow ran fine on Friday. On Monday the client's Google Sheet hasn't had a new row since Saturday morning, and the n8n executions list shows a column of failures, each with some version of "invalid_grant", "Token has been expired or revoked" or a 401 from a Google API.

Expired and revoked credentials are one of the most common reasons an n8n workflow that "has always worked" stops working. They're also predictable. Most of the causes are documented by Google, several have a fixed timer, and all of them can be caught before the client notices.

This post covers Google credentials specifically: OAuth2 credentials (Sheets, Gmail, Drive, Calendar) and service accounts. The same thinking applies to any OAuth-based credential in n8n.

The symptom

Credential failures show up in a few ways, depending on where the Google node sits in the workflow:

  • A Google action node fails mid-workflow. You get a failed execution with an authentication error. If the workflow has an error workflow set, this one does reach your alert. (If it doesn't, read Give every n8n workflow an error workflow first.)
  • A Google trigger stops picking things up. Gmail Trigger, Google Sheets Trigger and Google Drive Trigger are polling triggers. When their credential breaks, the problem is in the trigger, not in a later node. The error data your error workflow receives is shaped differently in that case (a trigger object instead of an execution), and depending on the setup you may simply see the workflow go quiet.
  • A node is set to continue on error. If someone set the Google node's On Error setting to continue, the execution can finish "successfully" with an error item that nothing downstream checks. That's the silent version, covered in Green doesn't mean it worked.

The common thread: it usually starts at a specific moment (an expiry, a password change, a policy change) and then every run fails the same way until someone reconnects the credential.

Why it happens

1. The 7-day Testing-mode expiry

This is the most common cause on self-hosted n8n with a custom Google OAuth app. When you create the OAuth consent screen and pick External as the user type, the app starts in Testing mode. Google's documentation is explicit: a project with an external user type and a publishing status of "Testing" is issued a refresh token that expires in 7 days, unless the only scopes requested are basic profile scopes (name, email, openid) (Google: Using OAuth 2.0 to access Google APIs). Gmail, Sheets and Drive scopes are not basic profile scopes, so the token stops working a week after you connect.

n8n's own troubleshooting section says the same: for apps with Publishing status set to Testing and User type set to External, consent and tokens expire after seven days, and the fix is to reconnect the credential (n8n docs: Google OAuth2 single service).

That's why the failure so often looks like "it broke over the weekend": it broke exactly seven days after the last reconnect.

Ways out:

  • If the client has Google Workspace and only their own users will authenticate, use an Internal user type. The 7-day rule is about external apps in Testing.
  • If the app has to be External, move it out of Testing by publishing it. Depending on the scopes, Google may require verification first.
  • On n8n Cloud, Managed OAuth2 ("Sign in with Google") is available for a list of Google nodes, including Gmail, Sheets, Drive and Calendar, and avoids running your own consent screen (same n8n page).

2. Refresh tokens that Google revokes

Even with a published app, Google lists several reasons a refresh token can stop working (Google: Refresh token expiration):

  • The user revoked the app's access.
  • The refresh token hasn't been used for six months.
  • The user changed their password and the token includes Gmail scopes.
  • The account exceeded the maximum number of live refresh tokens. There's a limit of 100 refresh tokens per Google Account per OAuth client ID, and creating a new one silently invalidates the oldest.
  • The user granted time-based access and it expired.
  • A Workspace admin set one of the requested services to Restricted (error admin_policy_enforced).
  • For Google Cloud scopes, an admin's session-length policy expired the session (an invalid_grant with error_subtype invalid_rapt).

Two of these catch agencies in particular. The password change one: a client's IT person rotates the password on the shared Gmail account the automation uses, and every Gmail workflow fails within the hour. And the 100-token limit: if the same Google account is connected over and over with the same OAuth client (for example a staging and production n8n, plus a few test credentials), the oldest token gets invalidated without warning.

3. Service account keys: expiry, disabling and org policy

Service accounts don't use refresh tokens. In n8n's Google Service Account credential you paste the service account email and private key, and n8n signs a JWT to get short-lived access tokens (n8n docs: Google Service Account credentials). So the "7 days" problem doesn't apply. Other things do:

  • Key expiry. By default a user-managed service account key never expires. But an organization can enforce the constraints/iam.serviceAccountKeyExpiryHours policy, which gives newly created keys an expiry time. Google's own docs warn that in production an expired key "could cause an accidental outage" (Google Cloud: Service account credentials). If a client's Google Cloud admin turns this on, the next key you create for n8n will have a timer on it.
  • Key creation blocked. Organizations created on or after 3 May 2024 enforce iam.disableServiceAccountKeyCreation by default (same page). This doesn't break existing keys, but it means a broken key can't simply be replaced without an admin.
  • Deleted or disabled keys and accounts. Someone cleaning up the Google Cloud project deletes "unused" keys or disables the service account. Every workflow using it fails immediately.
  • Lost access to the resource. A service account can only reach a Sheet or Drive folder that was shared with its email. If someone removes that share, the credential is fine but every call returns a permission error.

4. Changes on the n8n side

Not every credential failure is Google's doing. A self-hosted instance that changes its N8N_ENCRYPTION_KEY can no longer decrypt saved credentials. A credential that was shared from another project can be unshared. A workflow moved to a different project may lose access to credentials it used. These are rarer, but they produce the same symptom: all runs failing at the first node that uses the credential.

How to detect it by hand

Step 1: make sure the failure reaches someone

  • Give every production workflow an Error workflow in its Settings, using an Error Trigger that posts to Slack or email. Include execution.error.message, workflow.name, execution.lastNodeExecuted and execution.url in the message.
  • In that error workflow, add an IF node that checks whether the message contains strings such as invalid_grant, expired or revoked, unauthorized or 401, and send those to a separate, louder alert. A credential failure won't fix itself on retry, so it deserves a different response than a timeout.
  • Avoid Retry On Fail on Google nodes as a fix for auth errors. Retrying an expired token just delays the alert.
  • Check which Google nodes have On Error set to continue. If they do, make sure the error branch actually alerts.

Step 2: catch the trigger case

Because Gmail, Sheets and Drive triggers poll, a credential failure in the trigger is the case most likely to look like silence. Two complementary checks:

  • Handle the trigger variant in your error workflow. When the error comes from the trigger node there's no execution.id or execution.url, and the details are in trigger.error (n8n docs: Handle errors gracefully). Use an expression that falls back from one to the other, so the alert isn't blank.
  • Add an expected-run check. If a workflow that normally runs several times a day hasn't succeeded in 12 hours, alert, regardless of why. The previous post, catching triggers that stop firing, walks through building that watchdog with the n8n API.

Step 3: run a daily canary for each important credential

A canary is a tiny scheduled workflow that uses a credential for a harmless read, once a day, and alerts if it fails:

  • Add a Schedule Trigger set to run each morning before the client's working day.
  • Add one cheap Google node per credential: read one cell of a test Sheet, list one Drive file, or fetch one Gmail label.
  • Set the workflow's Error workflow to your alert workflow, or route each node's error output to an alert.
  • Name the workflow and nodes after the client and the credential, so the alert reads "Acme: Google Sheets (ops@acme.com) failed", not "Google Sheets1 failed".

The canary also helps with the six-months-unused rule: it keeps rarely used credentials in use.

Step 4: keep a credential register

For each client, write down which Google account or service account each credential uses, which OAuth client it was created with, whether the consent screen is Internal, External/Testing or External/Production, and when it was last reconnected. If anything is External/Testing, put a reminder in the calendar for day 6, or better, fix the consent screen. When a client says they're changing a password, you know which workflows to check.

How LeadPulse catches it

LeadPulse doesn't need to know why a Google token died to tell you it did. When you connect an n8n instance with its base URL and API key, LeadPulse reads executions, and its outcome rules flag the effects: a rising error rate on a workflow that usually succeeds, silence after N hours when a polling trigger stops producing successful runs, and a drop against the trailing 7-day pace. The checker runs every 10 minutes, sends one alert per incident rather than one per failed run, and sends a recovery note once the workflow delivers again.

The free n8n Health Check looks for this directly: it lists high error rates, credential failures and nodes that throw among the issues it scores, alongside workflows with no error workflow set.

Check your instance before Monday

Run the free n8n Health Check. Paste your n8n base URL and an API key (read-only is enough). It reads your workflows and recent executions once, scores them, and discards the key. No account is required; you enter your email to see the results. If it finds credential failures, fix the consent screen or service account first, then reconnect. To keep watching afterwards, the Free plan monitors 3 workflows on 1 instance with email alerts.

Sources