Insights

Fixing n8n Gmail OAuth2 Unauthorized Errors on Railway: Redirect URI Mismatch

3 min read#n8n#oauth2#gmail#railway#troubleshooting#redirect-uri

Who this is forEngineers and automation builders who self-host n8n on Railway with a custom domain and cannot reconnect a Gmail OAuth2 credential.

Gmail OAuth2 credentials in n8n sometimes fail with an Unauthorized error during reconnection, even when the Google Cloud project, consent screen, and client credentials all look correct. The failure is easy to misdiagnose as an expired token, and it can waste hours. This article explains how a mismatch between the redirect URI registered in Google Cloud Console and the callback URL n8n actually generates causes the error on a Railway-hosted instance with a custom domain. You will learn how to confirm the mismatch and fix it with two environment variables or a single Google Cloud change.

Summary

When reconnecting a Gmail OAuth2 credential in n8n returns Unauthorized, the cause is that the approved redirect URI in Google Cloud Console is registered under the custom domain (n8n.ggplab.xyz), but n8n redirects during the OAuth callback to the Railway default domain (*.up.railway.app).

Environment

Item Value
n8n hosting Railway
Custom domain n8n.ggplab.xyz
Railway default domain *.up.railway.app
Gmail credential OAuth2 (Google Cloud Console)

Symptoms

  1. Running a Gmail node in an n8n workflow returns the error The provided authorization grant ... is invalid, expired, revoked.
  2. Attempting to reconnect the credential (Reconnect) and selecting a Google account returns {"status":"error","message":"Unauthorized"}.
  3. The webhook itself works normally (200 OK, Workflow was started).

Because the webhook works, the n8n instance and its public routing are healthy. The failure is isolated to the OAuth flow.

Root Cause Analysis

What I checked (all normal)

  • The redirect URI https://n8n.ggplab.xyz/rest/oauth2-credential/callback is registered in the OAuth redirect URIs in Google Cloud Console.
  • The Gmail API is enabled.
  • The OAuth consent screen is configured correctly.
  • The Client ID and Client Secret are correct.

Since every item on the Google side checked out, the problem had to be in the URL n8n was sending.

Actual cause

When n8n builds the OAuth2 callback URL, it does not use the browser’s address bar. Instead, it builds the callback from the n8n server’s WEBHOOK_URL or other internal environment variables.

On Railway, you can attach a custom domain (n8n.ggplab.xyz), but if n8n’s environment variables (N8N_EDITOR_BASE_URL or WEBHOOK_URL) are still set to the Railway default domain, n8n does not know its own external address. The result is a mismatch:

Actual callback URL: https://xxx.up.railway.app/rest/oauth2-credential/callback
Registered URI:      https://n8n.ggplab.xyz/rest/oauth2-credential/callback
→ Mismatch → Google returns Unauthorized

Core mechanism

[User] Opens n8n.ggplab.xyz in the browser
         ↓
[n8n]  Clicks "Sign in with Google"
         ↓
[n8n]  Builds the OAuth callback URL from N8N_EDITOR_BASE_URL
         → https://xxx.up.railway.app/rest/oauth2-credential/callback  ← the problem
         ↓
[Google] Compares it with the registered redirect URI
         → Only https://n8n.ggplab.xyz/... is registered
         → Mismatch → Unauthorized

The browser reached n8n through the custom domain, but n8n itself generated the callback with the internal domain. Google only sees the URL n8n sends, so it rejects the request.

Fix

Set n8n’s base URL environment variables in Railway to the custom domain:

N8N_EDITOR_BASE_URL=https://n8n.ggplab.xyz
WEBHOOK_URL=https://n8n.ggplab.xyz

Alternatively, add the Railway default domain callback to the authorized redirect URIs in Google Cloud Console:

https://xxx.up.railway.app/rest/oauth2-credential/callback

The environment variable fix is the better choice. It makes n8n consistently generate URLs under the domain users actually visit, and it keeps the Google Cloud configuration to a single entry. Adding the Railway default domain works, but it leaves a second public address registered with Google, which you then have to maintain.

Lessons

  1. A custom domain is not the same as the app’s internal idea of its domain. An app behind a reverse proxy or CDN may not know its own external URL. You have to tell it explicitly with environment variables.
  2. When debugging OAuth redirect URIs, inspect the redirect_uri parameter. Check the browser’s network tab for the redirect_uri parameter sent to Google. This shows the exact URL n8n generated and usually reveals the cause immediately.
  3. When something that worked suddenly stops working, check both the token and the infrastructure. An expired OAuth refresh token (seven days in testing mode) and a redirect URI mismatch produce similar symptoms, both showing Unauthorized. It is tempting to suspect the token first, but you should also review the history of infrastructure changes, such as domain or hosting changes.
  • n8n official documentation: Environment Variables
  • When hosting n8n on Railway, setting N8N_EDITOR_BASE_URL is required.

Bottom line

A Gmail OAuth2 Unauthorized error during reconnection on a Railway-hosted n8n instance with a custom domain is most likely a redirect URI mismatch, not a bad token. Set N8N_EDITOR_BASE_URL and WEBHOOK_URL to the custom domain so the callback URL matches what is registered in Google Cloud Console. Check the redirect_uri parameter first to confirm the diagnosis before changing anything else.

Sources

Frequently asked questions

Why does n8n return Unauthorized when I reconnect a Gmail OAuth2 credential on Railway?
The OAuth callback URL is built from n8n's base URL environment variables. If those point to the Railway default domain while Google Cloud Console only lists the custom domain as a redirect URI, Google rejects the request with Unauthorized.
How do I fix the redirect URI mismatch in n8n on Railway?
Set N8N_EDITOR_BASE_URL and WEBHOOK_URL to your custom domain, such as https://n8n.ggplab.xyz. Alternatively, add the Railway default domain callback URL to the authorized redirect URIs in Google Cloud Console.

Want the full system? The Claude Code & Codex Skills guidebook collects the skills and subagents behind this blog, from $19.

Some links are affiliate links. If you sign up through them, BuildnWrite may earn a commission at no extra cost to you.

Tools in this post