Describe the problem/error/question
Error: Unsupported content type: text/html; charset=utf-8 when attempting Xero OAuth2 credential connection in n8n (self-hosted v1.113.3).
Critical Finding: GitHub OAuth2 works perfectly, proving infrastructure is correct. Issue is specific to Xero integration.
Has anyone successfully connected Xero OAuth2 credentials in self-hosted n8n v1.113.3? If so, what specific configuration made it work?
Is there a known issue with the Xero OAuth2 credential implementation that requires a workaround?
Note: The fact that GitHub OAuth works perfectly rules out all infrastructure, proxy, DNS, and environment configuration issues. This is specifically a Xero integration problem.
n8n setup
Environment
Setup: Self-hosted n8n on DigitalOcean (Ubuntu)
n8n Version: 1.113.3
Initial Setup: Docker with Caddy reverse proxy
Final Setup: Docker with Cloudflare Tunnel
Everything We Tried (In Order)
1. Caddy Reverse Proxy Configuration
Attempted fixes:
- Modified Caddyfile to add explicit header forwarding (
header_up Host,X-Real-IP,X-Forwarded-For,X-Forwarded-Proto) - Changed to minimal Caddy configuration (letting defaults handle headers)
- Removed all manual header configurations
- Multiple Caddy container restarts
Result: No change to error
2. n8n Environment Variables
Variables tested:
N8N_PROXY_HOPS=1(to trust reverse proxy)EXPRESS_TRUST_PROXY=true(alternative trust proxy method)WEBHOOK_URL=https://XXXXXX.com/(verified with trailing slash)N8N_PROTOCOL=httpsN8N_HOST=XXXXXX.com- Removed potentially conflicting variables (
N8N_PORT,NODE_ENV)
Result: Environment correctly set but error persisted
3. Complete Infrastructure Migration to Cloudflare Tunnel
Steps taken:
- Transferred domain DNS from GoDaddy to Cloudflare
- Created Cloudflare Tunnel (
cloudflared) - Changed port binding to
127.0.0.1:5678:5678(localhost only) - Configured tunnel with proper credentials and config file
- Verified 4 tunnel connections established successfully
- Confirmed n8n accessible via tunnel
Result: Infrastructure working perfectly (GitHub OAuth succeeds), but Xero still fails with identical error
4. Xero Application Configuration
Attempts:
- Verified redirect URI exact match:
https://XXXXXX.com/rest/oauth2-credential/callback - Created completely new Xero app from scratch
- Verified app type: Web app
- Confirmed scopes match tutorial requirements
- Generated new Client ID and Client Secret multiple times
- Tested with brand new credentials
Result: Same error with both old and new Xero apps
5. Diagnostic Tests
Tests performed:
- GitHub OAuth2 test:
SUCCESS (proves OAuth infrastructure works) - n8n web interface access:
Working - Docker container networking:
Verified listening on port 5678 - Cloudflare Tunnel status:
Active with 4 registered connections - Localhost curl test:
Returns n8n HTML correctly - Multiple browser tests: Incognito, different browsers
- Live log monitoring during connection attempts
Key Evidence
- GitHub OAuth works → Infrastructure is NOT the problem
- Xero OAuth fails with brand new app → Not a corrupted app configuration
- Error is identical across all infrastructure changes → Problem is in n8n’s Xero integration code or Xero’s API response handling
What is the error message (if any)?
Error: Unsupported content type: text/html; charset=utf-8
More details : HTML of the Xero homepage.
Failed to connect. The window can be closed now.
Node
{
“nodes”: [
{
“parameters”: {
“url”: “=https://api.xero.com/api.xro/2.0/Accounts”,
“authentication”: “genericCredentialType”,
“genericAuthType”: “oAuth2Api”,
“sendHeaders”: true,
“headerParameters”: {
“parameters”: [
{
“name”: “xero-tenant-id”,
“value”: “removed”
}
]
},
“options”: {}
},
“type”: “n8n-nodes-base.httpRequest”,
“typeVersion”: 4.2,
“position”: [
816,
-2368
],
“id”: “d306435a-024c-4069-84b3-fe88efe613ba”,
“name”: “Xero - Get Chart of Accounts1”,
“credentials”: {
“oAuth2Api”: {
“id”: “kmN7PKdcEzrOHQBF”,
“name”: “Unnamed credential”
}
}
}
],
“connections”: {
“Xero - Get Chart of Accounts1”: {
“main”: [
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “5db59f632211c3294bc850ecaf66a632b1d2a9cd423b9f3ee02d96064b530e10”
}
}
