Problem: n8n Email Nodes Fail Without the Right Auth Setup
Connecting n8n to Gmail or an SMTP server looks simple until you hit OAuth errors, "less secure app" blocks, or silent delivery failures. The Gmail node and the Send Email (SMTP) node have different credential requirements — mixing them up wastes an hour.
You'll learn:
- How to configure Gmail with OAuth2 (no app passwords)
- How to connect any SMTP provider (Resend, Mailgun, AWS SES)
- How to build a trigger-based email workflow with error handling
Time: 20 min | Difficulty: Intermediate
Why Email Auth Is Confusing in n8n
n8n has two separate email nodes:
| Node | Protocol | Auth method | Best for |
|---|---|---|---|
| Gmail | Gmail API | OAuth2 | Personal Gmail, Google Workspace |
| Send Email | SMTP | Username + password / API key | Resend, Mailgun, SES, Postfix |
Google disabled basic auth for Gmail in 2023. If you try to use the Send Email node with smtp.gmail.com and a regular password, it will fail. Use the Gmail node with OAuth2 instead.
Solution
Step 1: Create a Google OAuth2 Credential (Gmail Node)
You need a Google Cloud project to generate OAuth2 credentials.
In Google Cloud Console:
- Go to console.cloud.google.com → APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Application type: Web application
- Add this to Authorized redirect URIs:
https://your-n8n-domain.com/rest/oauth2-credential/callback
For local dev:
http://localhost:5678/rest/oauth2-credential/callback
- Copy the Client ID and Client Secret
Enable the Gmail API:
APIs & Services → Library → search "Gmail API" → Enable
In n8n:
- Go to Settings → Credentials → New
- Search Gmail OAuth2 API
- Paste Client ID and Client Secret
- Click Sign in with Google and authorize
Expected: Credential status shows a green checkmark.
If it fails:
redirect_uri_mismatch→ The URI in Google Console doesn't exactly match your n8n URL including the protocol (https://vshttp://)Access blocked→ Your OAuth consent screen is in "Testing" mode; add your email as a test user under OAuth consent screen → Test users
Step 2: Configure SMTP for Transactional Email Providers
For production email (not Gmail), use the Send Email node with an SMTP provider. Resend and Mailgun both offer generous free tiers.
Resend (recommended for developers):
| Field | Value |
|---|---|
| Host | smtp.resend.com |
| Port | 465 |
| SSL/TLS | true |
| User | resend |
| Password | Your Resend API key |
Mailgun:
| Field | Value |
|---|---|
| Host | smtp.mailgun.org |
| Port | 587 |
| SSL/TLS | false (uses STARTTLS) |
| User | postmaster@your-domain.mailgun.org |
| Password | Mailgun SMTP password (not API key) |
In n8n:
- Settings → Credentials → New → SMTP
- Fill in the fields above
- Click Test — n8n sends a test email to verify the connection
If test fails:
Connection refusedon port 465 → Try port 587 with SSL disabled (provider may require STARTTLS)Authentication failed→ Double-check you're using the SMTP password, not the API key — they're different on Mailgun
Step 3: Build a Trigger-Based Email Workflow
This workflow sends an email when a new row is added to a webhook (e.g., a form submission).
Workflow: Form submission → Send confirmation email
[Webhook] → [Set node] → [Gmail / Send Email]
Webhook node config:
{
"httpMethod": "POST",
"path": "form-submission",
"responseMode": "onReceived"
}
Set node — map form fields to clean variables:
// In the Set node, use these expressions
// Maps messy webhook body to predictable field names
{
"email": "{{ $json.body.email }}",
"name": "{{ $json.body.name }}",
"subject": "Thanks for your submission, {{ $json.body.name }}"
}
Gmail node config:
To: {{ $json.email }}
Subject: {{ $json.subject }}
Message: Hi {{ $json.name }}, we received your submission and will follow up within 24 hours.
Test with curl:
curl -X POST https://your-n8n-domain.com/webhook/form-submission \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "name": "Ada"}'
Expected: Email arrives within 5 seconds.
Step 4: Add Error Handling for Delivery Failures
Silent failures kill trust in automation. Add an error branch so you know when emails don't send.
Enable error output on the email node:
- Click the email node → Settings tab
- Toggle Continue on Fail to
on - Connect a new branch from the red error output
Error branch: log to a Google Sheet or send a Slack alert:
[Email node error output] → [IF node: check $json.error exists] → [Slack / Sheets]
IF node expression:
// Returns true when the email node failed
{{ $json.error !== undefined }}
Slack alert node message:
Email delivery failed for {{ $('Set').item.json.email }}
Error: {{ $json.error.message }}
Workflow: {{ $workflow.name }}
Verification
Send a test webhook and confirm delivery:
# Send test payload
curl -X POST https://your-n8n-domain.com/webhook/form-submission \
-H "Content-Type: application/json" \
-d '{"email": "your-email@example.com", "name": "Test User"}'
Check in n8n:
- Open the workflow → Executions tab
- Confirm status is Success (green)
- Click the Gmail/Send Email node in the execution to see the full response payload
Check delivery:
- Gmail: Check inbox and Sent folder
- Resend/Mailgun: Check the provider dashboard for delivery status and open tracking
What You Learned
- Gmail requires OAuth2 — the SMTP node with
smtp.gmail.comwill not work - The Send Email SMTP node is the right choice for transactional providers like Resend, Mailgun, and SES
- The Set node is essential for normalizing webhook data before it reaches email nodes
- Continue on Fail + an error branch prevents silent delivery failures in production
Limitation: Gmail OAuth2 tokens expire. If your n8n instance goes offline for an extended period, you may need to re-authorize the credential. For high-volume sending (>500/day), use a dedicated SMTP provider — Gmail's API has daily sending limits.
Tested on n8n 1.82, Gmail API v1, Resend SMTP, Ubuntu 24.04