Skip to content

fix(http): honor timeout during connect without redirects#10819

Merged
jasonsaayman merged 4 commits intoaxios:v1.xfrom
cyphercodes:fix/http-connect-timeout-maxredirects-0
Apr 30, 2026
Merged

fix(http): honor timeout during connect without redirects#10819
jasonsaayman merged 4 commits intoaxios:v1.xfrom
cyphercodes:fix/http-connect-timeout-maxredirects-0

Conversation

@cyphercodes
Copy link
Copy Markdown
Contributor

@cyphercodes cyphercodes commented Apr 28, 2026

Summary

  • add a wall-clock timeout for the native HTTP/HTTPS transport used when maxRedirects === 0
  • reuse the existing timeout error message/code handling and clear the timer on response, close, or settle
  • add regression coverage for sockets that remain in the TCP connect phase, including disabled timeout: '0'

Fixes #10818

Testing

  • npm run test:vitest:unit -- tests/unit/adapters/http.test.js -t "TCP connect|timeout set to zero|timeout property"
  • npx eslint lib/adapters/http.js tests/unit/adapters/http.test.js

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Confidence score: 3/5

  • There is a concrete regression risk in lib/adapters/http.js: the new connect-phase timer can treat timeout: '0' on native transport as an immediate abort, changing prior no-timeout behavior.
  • Because this is a user-facing behavior change with medium severity (6/10) and high confidence (8/10), this sits in a moderate-risk range rather than a safe-to-merge baseline.
  • Pay close attention to lib/adapters/http.js - verify timeout normalization for '0' preserves the previous no-timeout semantics on native transport.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/adapters/http.js">

<violation number="1" location="lib/adapters/http.js:1054">
P2: New connect-phase timer causes `timeout: '0'` on native transport to abort immediately, regressing prior no-timeout behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread lib/adapters/http.js Outdated
@cyphercodes cyphercodes force-pushed the fix/http-connect-timeout-maxredirects-0 branch from 9824ef4 to 432a4d8 Compare April 28, 2026 17:15
@cyphercodes
Copy link
Copy Markdown
Contributor Author

Thanks, cubic found that timeout: '0' would schedule the new connect timer immediately. Fixed in 432a4d8 by only starting the wall-clock timer for parsed timeouts greater than 0 and added regression coverage for disabled timeout: '0'. @cubic-dev-ai please re-run.

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented Apr 28, 2026

Thanks, cubic found that timeout: '0' would schedule the new connect timer immediately. Fixed in 432a4d8 by only starting the wall-clock timer for parsed timeouts greater than 0 and added regression coverage for disabled timeout: '0'. @cubic-dev-ai please re-run.

@cyphercodes I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@jasonsaayman
Copy link
Copy Markdown
Member

Thanks for the PR @cyphercodes,

This is a clean fix, and the analysis matches what I was expecting from the issue. I am happy to land it. Two small things, before I merge:

  1. Duplicate timer on the native path. In lib/adapters/http.js around line 1047, when isNativeTransport && timeout > 0 we now arm the wall clock timer and still register req.setTimeout(timeout, handleRequestTimeout) after it. The wall clock will almost always pre-empt, so the second registration is mostly vestigial in this branch. Worth either skipping it when the wall clock is armed, or routing both through a single handler. Cleanup, not a bug.

  2. Defensive clear in onFinished. The req.once('close', ...) handler covers the cleanup today, but a clearConnectPhaseTimer() inside onFinished would future-proof against any reordering of close vs settle. Optional.

One thing I want to call out, so it is on the record: this changes time to first byte semantics on the maxRedirects === 0 path. After the connection succeeds, the wall clock is cleared in handleResponse, so streamed bodies are still governed by the existing req.setTimeout inactivity logic, which is what I want. Just confirming that was intentional and not an accident of where the clear landed.

Let me know when the PR has been updated, and I will take a look again

@jasonsaayman jasonsaayman added priority::medium A medium priority commit::fix The PR is related to a bugfix status::changes-requested A reviewer requested changes to the PR status::needs-rebase The PR requires a rebase and removed status::needs-rebase The PR requires a rebase labels Apr 30, 2026
@cyphercodes
Copy link
Copy Markdown
Contributor Author

Updated this PR to address the two follow-ups:

  • Reused a single timeout handler for both the native connect-phase wall-clock timer and ClientRequest#setTimeout.
  • Added a defensive clearConnectPhaseTimer() inside onFinished() as well.

Local verification:

  • npm ci
  • npx eslint lib/adapters/http.js
  • npx vitest run --project unit tests/unit/adapters/http.test.js -t "timeout property during TCP connect|timeout set to zero during TCP connect"
  • git diff --check

I also ran the full npx vitest run --project unit tests/unit/adapters/http.test.js; the two targeted timeout tests passed, but the full file still had two unrelated local/environment-sensitive failures (DNS > should handle errors timed out resolving no-such-domain-987654.com, and one HTTP2 session test errored with Premature close).

@jasonsaayman jasonsaayman removed the status::changes-requested A reviewer requested changes to the PR label Apr 30, 2026
@jasonsaayman jasonsaayman merged commit ad68e1a into axios:v1.x Apr 30, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit::fix The PR is related to a bugfix priority::medium A medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(http): timeout not honored during TCP connect phase when maxRedirects=0

2 participants