Skip to content

net: warn on keep-alive delays truncated to zero - #65528

Open
zeexzeex wants to merge 1 commit into
nodejs:mainfrom
zeexzeex:net-keepalive-warning
Open

net: warn on keep-alive delays truncated to zero#65528
zeexzeex wants to merge 1 commit into
nodejs:mainfrom
zeexzeex:net-keepalive-warning

Conversation

@zeexzeex

Copy link
Copy Markdown

socket.setKeepAlive() takes its delays in milliseconds, but the underlying
socket options are configured in whole seconds. A positive value below 1000
rounds down to 0, which leaves the system default in place instead of
applying the requested timing:

socket.setKeepAlive(true, 400); // TCP_KEEPIDLE is left unchanged

Nothing indicates that the value had no effect. There is no exception, no
warning, and the return value is the socket either way, so the caller has no
way to tell that keep-alive was not configured as asked.

Sub-second timings cannot be supported: uv_tcp_keepalive() takes seconds and
rejects a delay below 1. This makes the truncation visible instead.

Changes

  • Emit a KeepAliveWarning when a positive initialDelay or interval is
    truncated to zero. 0 keeps its documented meaning of leaving the current
    setting unchanged and does not warn, and nothing is reported when keep-alive
    is being disabled.
  • Document the result of the truncation in net.md. The rounding itself was
    already described; what was missing was that a value below 1000 ends up not
    being applied at all.
  • Fix two existing tests that passed values below 1000 ms which did not match
    what their comments described.

Refs: #57712

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem. labels Aug 25, 2026
@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.21%. Comparing base (4b5e86c) to head (6222f2f).
⚠️ Report is 264 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65528      +/-   ##
==========================================
+ Coverage   90.14%   90.21%   +0.06%     
==========================================
  Files         751      771      +20     
  Lines      253679   264651   +10972     
  Branches    47789    50241    +2452     
==========================================
+ Hits       228671   238746   +10075     
- Misses      16264    16910     +646     
- Partials     8744     8995     +251     
Files with missing lines Coverage Δ
lib/net.js 94.60% <100.00%> (+0.04%) ⬆️

... and 204 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zeexzeex
zeexzeex force-pushed the net-keepalive-warning branch from 1e4c167 to cc29daa Compare September 4, 2026 01:25
@mcollina

mcollina commented Sep 4, 2026

Copy link
Copy Markdown
Member

I don't think we should be landing a warning for this. I think we should be throwing an error.

@zeexzeex
zeexzeex force-pushed the net-keepalive-warning branch from cc29daa to e36ca60 Compare September 7, 2026 01:49
@zeexzeex

zeexzeex commented Sep 7, 2026

Copy link
Copy Markdown
Author

@mcollina Agreed, switched to throwing. uv_tcp_keepalive() already rejects a delay outside [1, 32767] seconds, so ERR_OUT_OF_RANGE now covers both ends. Non-positive values keep their documented "leave unchanged" meaning.

This surfaced test-async-hooks-http-parser-destroy, which sets keepAliveMsecs: 100 and so had never configured keep-alive at all. Raised to 1000.

Five tests also pass Infinity through Agent. That reads as "no timeout" but truncates to 0 today, so it has the same defect. I left it accepted rather than throwing, because the fix is a design choice rather than an obvious one: reject it, clamp it to the maximum, or keep the current behaviour and document it. It also looks like an established idiom, so it seemed better to let you pick instead of settling it here.

Two questions: does this need semver-major? And Agent reaches this path, so keepAliveMsecs below 1000 now throws instead of being ignored. Full parallel suite is green.

The keep-alive delays are given in milliseconds but the underlying
socket options are configured in whole seconds, so a positive value
below 1000 ms rounds down to 0. That leaves the system default in
place instead of applying the requested timing, and there is nothing
to indicate that the value had no effect. uv_tcp_keepalive() already
rejects a delay outside [1, 32767] seconds, so the value is treated as
invalid one layer down.

Throw ERR_OUT_OF_RANGE for a positive initialDelay or interval that
cannot be applied as requested, covering both the truncation to zero
and the upper bound the socket options can carry. A non-positive value
keeps its documented meaning of leaving the current setting unchanged,
and Infinity is accepted as "no timeout" by callers such as Agent.

Three existing tests passed delays that were silently ignored;
test-async-hooks-http-parser-destroy had never configured keep-alive
at all despite asking for it.

Refs: nodejs#57712
Signed-off-by: Avocado <ujubongbong@gmail.com>
@zeexzeex
zeexzeex force-pushed the net-keepalive-warning branch from e36ca60 to 6222f2f Compare September 7, 2026 01:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants