nodejs / nodejs/node

EALREADY when reconnecting socket after destroying immediately after connecting

Open
#55,519 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

net
Dominant language
JavaScript
Stars
122k
Forks
37.3k
Avg merge
4d 2h
Merged PRs (30d)
283

Description

Version

v22.10.0

Platform
Darwin xxx.local 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:21 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8103 arm64
Subsystem

No response

What steps will reproduce the bug?
import { Socket } from 'node:net';

const socket = new Socket();
socket.on('error', (err) => {
  console.log(err);
});
socket.on('connect', () => {
  console.log('connected');
});
socket.connect({ host: 'google.com', port: 80 });
socket.once('close', () => {
  console.log('closed');
  socket.connect({ host: 'google.com', port: 80 });
});
socket.destroy();
How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

Seeing

closed
connected

in the console.

What do you see instead?
closed
Error: connect EALREADY 142.250.179.174:2404 - Local (192.168.178.178:61323)
    at internalConnect (node:net:1097:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18)
    at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1496:9)
    at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:132:8) {
  errno: -37,
  code: 'EALREADY',
  syscall: 'connect',
  address: '142.250.179.174',
  port: 2404
}
Additional information

Calling socket.destroySoon(); or socket.end(); does work as intended, but IMO socket.destroy(); should also allow a reconnect immediately afterwards. Note that calling socket.destroy(); on a socket that has been connected does allow for immediate reconnect afterwards as expected.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the provided node:net Socket example on the reported platform, then trace the Socket connect/destroy lifecycle and the internalConnect path named in the stack trace. Done means an immediate reconnect after destroy() reaches connected without EALREADY, while the already-connected destroy-and-reconnect behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.