n8n - ✅(Solved) Fix OAuth2 token refresh fails behind corporate proxy (axios `proxy: false` missing in `@n8n/client-oauth2`) [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
n8n-io/n8n#28225Fetched 2026-04-10 03:44:42
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Author
Timeline (top)
labeled ×5commented ×1mentioned ×1subscribed ×1

Error Message

error There was a problem in 'Microsoft Outlook Trigger' node: 'Unsupported content type: text/html' NodeApiError: Method not allowed - please check you are using the right HTTP method at PollContext.requestWithAuthentication (request-helper-functions.ts:1550:10) at PollContext.microsoftApiRequest (transport/index.ts:58:10)

Root Cause

n8n's proxy architecture has two layers:

  1. Global proxy agents (HttpProxyManager / HttpsProxyManager) installed by installGlobalProxyAgent() in packages/core/src/http-proxy.ts — these replace http.globalAgent and https.globalAgent and use proxy-from-env to route requests through the configured proxy.

  2. Per-request proxy agents created by createHttpsProxyAgent() — these are set on individual axios requests via the axios interceptor in request-helper-functions.ts. The interceptor also sets axios.defaults.proxy = false (line 80) to disable axios's built-in proxy handling.

The @n8n/client-oauth2 package (packages/@n8n/client-oauth2/src/client-oauth2.ts) uses axios.request(requestConfig) for token exchange and refresh. Although it uses the same axios module instance, the requestConfig does not explicitly include proxy: false.

In environments with proxy chaining (e.g., forwarding proxy → upstream filtering proxy), axios's built-in proxy detection reads the HTTPS_PROXY environment variable and attempts its own proxy handling. This conflicts with the global HttpsProxyManager agent, effectively double-proxying the request. The upstream proxy rejects the malformed tunneled request with METHOD_NOT_ALLOWED.

Fix Action

Fix

Add proxy: false to the axios request config in @n8n/client-oauth2:

File: packages/@n8n/client-oauth2/src/client-oauth2.ts

// Before (current code):
const response = await axios.request(requestConfig);

// After (fixed):
const response = await axios.request({ ...requestConfig, proxy: false });

This ensures the OAuth2 client's requests use n8n's custom proxy agents (via the global agent) instead of axios's built-in proxy handling, consistent with how all other n8n HTTP requests work.

Workaround

Patch the compiled file on container startup by adding this to the entrypoint/init script:

sed -i 's/const response = await axios_1.default.request(requestConfig)/requestConfig.proxy = false; const response = await axios_1.default.request(requestConfig)/' /path/to/app/node_modules/@n8n/client-oauth2/dist/client-oauth2.js

PR fix notes

PR #28513: fix: Disable axios built-in proxy for OAuth2 token requests

Description (problem / solution / changelog)

Summary

OAuth2 token refresh fails in corporate proxy-chain environments with Unsupported content type: text/html. The proxy returns an HTML error page (METHOD_NOT_ALLOWED) instead of a JSON token response.

Root cause: Two proxy layers conflict:

  1. installGlobalProxyAgent() replaces http.globalAgent / https.globalAgent with HttpProxyManager / HttpsProxyManager (in packages/core/src/http-proxy.ts). These use proxy-from-env to route requests through the configured proxy.
  2. Axios's own built-in proxy handling also reads HTTPS_PROXY from the environment and attempts to proxy the request itself.

n8n already sets axios.defaults.proxy = false in packages/core to prevent this conflict for all regular workflow HTTP requests. However, @n8n/client-oauth2 makes direct axios.request() calls without an explicit proxy: false in the per-request config, so it relies on that side-effect import being loaded first — a fragile dependency that breaks in proxy-chain environments.

Fix: Add proxy: false directly to the requestConfig object in ClientOAuth2.accessTokenRequest(). This makes the OAuth2 client self-contained and consistent with how every other outbound HTTP request in n8n disables axios's built-in proxy.

Related Linear tickets, Github issues, and Community forum posts

Review / Merge checklist

  • I have seen this code, I have run this code, and I take responsibility for this code.
  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with Backport to Beta, Backport to Stable, or Backport to v1 (if the PR is an urgent fix that needs to be backported)

Changed files

  • packages/@n8n/client-oauth2/src/client-oauth2.ts (modified, +4/-0)
  • packages/@n8n/client-oauth2/test/client-oauth2.test.ts (modified, +1/-0)

Code Example

error   There was a problem in 'Microsoft Outlook Trigger' node: 'Unsupported content type: text/html'
NodeApiError: Method not allowed - please check you are using the right HTTP method
    at PollContext.requestWithAuthentication (request-helper-functions.ts:1550:10)
    at PollContext.microsoftApiRequest (transport/index.ts:58:10)

---

// Before (current code):
const response = await axios.request(requestConfig);

// After (fixed):
const response = await axios.request({ ...requestConfig, proxy: false });

---

sed -i 's/const response = await axios_1.default.request(requestConfig)/requestConfig.proxy = false; const response = await axios_1.default.request(requestConfig)/' /path/to/app/node_modules/@n8n/client-oauth2/dist/client-oauth2.js
RAW_BUFFERClick to expand / collapse

Bug Description

When n8n runs behind a corporate HTTP proxy, the OAuth2 token refresh fails with Method not allowed / Unsupported content type: text/html. The response is an HTML error page from the proxy instead of the expected JSON token response.

This happens because the @n8n/client-oauth2 package does not set proxy: false on its axios requests, while the n8n core (request-helper-functions.js:80) does set axios.defaults.proxy = false. This causes a double-proxying conflict: axios's built-in proxy handling AND n8n's custom HttpsProxyManager global agent both attempt to route the request through the proxy simultaneously.

To Reproduce

  1. Deploy n8n (tested on v2.11.3) behind a corporate HTTP proxy with proxy chaining (e.g., a forwarding proxy that chains to an upstream filtering proxy)
  2. Set standard proxy environment variables: HTTP_PROXY, HTTPS_PROXY, NO_PROXY
  3. Configure a Microsoft Outlook OAuth2 credential
  4. Activate a workflow with a Microsoft Outlook Trigger (poll-based)
  5. Wait for the OAuth2 token to expire and trigger a refresh

Expected behavior

The OAuth2 token refresh should succeed, and the trigger should poll Microsoft Graph API normally.

Debug Info

Expected behavior

The OAuth2 token refresh should succeed, and the trigger should poll Microsoft Graph API normally.

Actual behavior

The token refresh request to https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token fails. The corporate proxy returns an HTML error page with METHOD_NOT_ALLOWED instead of a JSON token response.

Error in n8n logs:

error   There was a problem in 'Microsoft Outlook Trigger' node: 'Unsupported content type: text/html'
NodeApiError: Method not allowed - please check you are using the right HTTP method
    at PollContext.requestWithAuthentication (request-helper-functions.ts:1550:10)
    at PollContext.microsoftApiRequest (transport/index.ts:58:10)

Root cause analysis

n8n's proxy architecture has two layers:

  1. Global proxy agents (HttpProxyManager / HttpsProxyManager) installed by installGlobalProxyAgent() in packages/core/src/http-proxy.ts — these replace http.globalAgent and https.globalAgent and use proxy-from-env to route requests through the configured proxy.

  2. Per-request proxy agents created by createHttpsProxyAgent() — these are set on individual axios requests via the axios interceptor in request-helper-functions.ts. The interceptor also sets axios.defaults.proxy = false (line 80) to disable axios's built-in proxy handling.

The @n8n/client-oauth2 package (packages/@n8n/client-oauth2/src/client-oauth2.ts) uses axios.request(requestConfig) for token exchange and refresh. Although it uses the same axios module instance, the requestConfig does not explicitly include proxy: false.

In environments with proxy chaining (e.g., forwarding proxy → upstream filtering proxy), axios's built-in proxy detection reads the HTTPS_PROXY environment variable and attempts its own proxy handling. This conflicts with the global HttpsProxyManager agent, effectively double-proxying the request. The upstream proxy rejects the malformed tunneled request with METHOD_NOT_ALLOWED.

Why it works without proxy chaining

In simple proxy setups (single proxy, no upstream filtering), the double-proxying may not cause visible issues because the proxy handles the redundant request gracefully. The bug only manifests when the proxy chain has strict request validation.

Fix

Add proxy: false to the axios request config in @n8n/client-oauth2:

File: packages/@n8n/client-oauth2/src/client-oauth2.ts

// Before (current code):
const response = await axios.request(requestConfig);

// After (fixed):
const response = await axios.request({ ...requestConfig, proxy: false });

This ensures the OAuth2 client's requests use n8n's custom proxy agents (via the global agent) instead of axios's built-in proxy handling, consistent with how all other n8n HTTP requests work.

Workaround

Patch the compiled file on container startup by adding this to the entrypoint/init script:

sed -i 's/const response = await axios_1.default.request(requestConfig)/requestConfig.proxy = false; const response = await axios_1.default.request(requestConfig)/' /path/to/app/node_modules/@n8n/client-oauth2/dist/client-oauth2.js

Operating System

Linux

n8n Version

2.11.3

Node.js Version

24.4.0

Database

SQLite (default)

Execution mode

main (default)

Hosting

self hosted

extent analysis

TL;DR

Add proxy: false to the axios request config in @n8n/client-oauth2 to prevent double-proxying conflicts.

Guidance

  • Identify the @n8n/client-oauth2 package version and verify if it has the fix for double-proxying.
  • Check the proxy environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY) to ensure they are correctly set.
  • Test the OAuth2 token refresh with the fix applied to confirm the resolution of the Method not allowed error.
  • Consider applying the provided workaround if updating the @n8n/client-oauth2 package is not feasible.

Example

The fix involves modifying the client-oauth2.ts file in @n8n/client-oauth2 to include proxy: false in the axios request config:

const response = await axios.request({ ...requestConfig, proxy: false });

Alternatively, the workaround can be applied using a sed command to patch the compiled file:

sed -i 's/const response = await axios_1.default.request(requestConfig)/requestConfig.proxy = false; const response = await axios_1.default.request(requestConfig)/' /path/to/app/node_modules/@n8n/client-oauth2/dist/client-oauth2.js

Notes

The provided fix and workaround assume a specific version of @n8n/client-oauth2 and may not be applicable to other versions. Additionally, the workaround involves modifying the compiled file, which may have implications for future updates or maintenance.

Recommendation

Apply the workaround by patching the compiled file using the sed command, as it provides a temporary solution until the @n8n/client-oauth2 package can be updated with the fix.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The OAuth2 token refresh should succeed, and the trigger should poll Microsoft Graph API normally.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING