Skip to content

Fix AggregateError crashes on Node.js 20+ caused by Happy Eyeballs (autoSelectFamily) - #61

Closed
dirkwa wants to merge 1 commit into
SignalK:masterfrom
dirkwa:fix/node20-autoselectfamily-workaround
Closed

dirkwa wants to merge 1 commit into
SignalK:masterfrom
dirkwa:fix/node20-autoselectfamily-workaround

Conversation

@dirkwa

@dirkwa dirkwa commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add workaround for Node.js 20+ "Happy Eyeballs" (RFC 6555) causing AggregateError in HTTP libraries

Problem

Node.js 20+ enables autoSelectFamily by default, which implements RFC 6555 "Happy Eyeballs" - attempting IPv4 and IPv6 connections simultaneously. When both connection attempts fail, Node.js throws an AggregateError.

Libraries using @cypress/request (including node-telegram-bot-api used by node-red-contrib-telegrambot) don't handle AggregateError properly, causing unhandled exceptions and plugin crashes.

Example error:

AggregateError
    at internalConnectMultiple (node:net:1121:18)
    at afterConnectMultiple (node:net:1688:7)

Solution

Disable autoSelectFamily at plugin initialization by calling net.setDefaultAutoSelectFamily(false). This is placed at the very top of index.js before any dependencies are loaded, ensuring it applies globally to all network connections.

References

Testing

Tested on SignalK server running Node.js v24.13.0 with node-red-contrib-telegrambot. Before the fix, continuous AggregateError crashes occurred. After the fix, no errors and stable operation.

Disable autoSelectFamily (Happy Eyeballs RFC 6555) to prevent
AggregateError crashes in Node-RED nodes using @cypress/request
(e.g., node-red-contrib-telegrambot).

Node.js 20+ enables autoSelectFamily by default, which tries IPv4
and IPv6 connections simultaneously. When both fail, it throws
AggregateError which older HTTP libraries don't handle properly.

Fixes issues with:
- node-telegram-bot-api (uses @cypress/request)
- Other Node-RED nodes using deprecated request libraries

References:
- yagop/node-telegram-bot-api#1193
- nodejs/node#46790
@sbender9

sbender9 commented Jan 23, 2026 •

Copy link
Copy Markdown
Member

Don't love this because it is global, right? This will affect the server and other plugins.

If we want to turn this off, we should probably do it in the server.

Or you could do it in a function node?

What do you think @tkurki

@dirkwa

dirkwa commented Jan 24, 2026 •

Copy link
Copy Markdown
Contributor Author

@sbender9

I understand your concerns, so we should address this properly. Node-Red will be a show stopper to lift SignalK to node 24.

You have not been a lot involved in the Universal Installer that runs podman containers.
I am currently working on a PR that it is all controlled "in the background" from the signalk-server.

My idea would be to put the node-red-plugin into a container and during App Store install to spin it up.

Architecture Sketch

┌─────────────────────────────────────────────────┐
│  Pod: signalk                                   │
│                                                 │
│  ┌─────────────────┐    ┌────────────────────┐  │
│  │ signalk-server  │◄───│ node-red           │  │
│  │                 │ WS │                    │  │
│  │ localhost:3000  │───►│ Uses existing      │  │
│  │                 │    │ node-red-contrib-  │  │
│  │                 │    │ signalk nodes      │  │
│  └─────────────────┘    └────────────────────┘  │
└─────────────────────────────────────────────────┘

Node-RED just uses the existing node-red-contrib-signalk nodes pointing at localhost:3000. No special integration needed.

Why This Is a Great Fit

Complete process isolation - Node-RED runs in its own container with its own Node.js process. The net.setDefaultAutoSelectFamily(false) stays contained. SignalK core and other plugins are completely unaffected.

Other benefits you get for free:

  • Node-RED can have its own Node.js version (pin to whatever works best)
  • Memory limits / resource isolation
  • Easier upgrades (swap container image, done)
  • Node-RED's npm dependencies can't conflict with SignalK's
  • Crash isolation - Node-RED dying doesn't take down SignalK
  • Security - Node-RED flows can be sandboxed from the host

If this interests you than I am more than happy to share additional details.
Feel free to close this PR.

@sbender9

sbender9 commented Jan 25, 2026 •

Copy link
Copy Markdown
Member

The current node-red contrib does not work in a separate node-red process. It uses the plugin apis. Some of the functionality is not available externally.

@dirkwa

dirkwa commented Jan 25, 2026

Copy link
Copy Markdown
Contributor Author

The current node-red contrib does not work in a separate node-red process. It uses the plugin apis. Some of the functionality is not available externally.

I am fully aware of this, it would be a refactoring to a containerized runtime. Would you be open minded for this, if I give it a try?

@sbender9

Copy link
Copy Markdown
Member

The current node-red contrib does not work in a separate node-red process. It uses the plugin apis. Some of the functionality is not available externally.

I am fully aware of this, it would be a refactoring to a containerized runtime. Would you be open minded for this, if I give it a try?

yes, but I think we need two versions of the nodes or to make the nodes detect when running embedded and use the plugin api's, and one that uses WebSockets. Nodes like input-handler and send-nmea2000/0183 won't work unless some support is added to the server to do these over WS.

@sbender9

Copy link
Copy Markdown
Member

This issue is only problem for node-red-contrib-telegrambot or for node-red in general? I thought I tested with v24.

@dirkwa

dirkwa commented Jan 25, 2026

Copy link
Copy Markdown
Contributor Author

This issue is only problem for node-red-contrib-telegrambot or for node-red in general? I thought I tested with v24.

I have not tested everything in detail tbo. That was the first thing that I saw was broken.

yes, but I think we need two versions of the nodes or to make the nodes detect when running embedded and use the plugin api's, and one that uses WebSockets. Nodes like input-handler and send-nmea2000/0183 won't work unless some support is added to the server to do these over WS.

Thanks for the hint. I will look into it mid Feb I think, after returning from my trip.

@tkurki

tkurki commented Jan 25, 2026

Copy link
Copy Markdown
Member

No, let’s not start changing global node level defaults for a single add on of a plugin.

Why would this even crop up now if it’s been in Node since 20?

Remote SK nodes is 100% separate issue, let’s try to keep discussion organised. End users do read this stuff and mixing separate things into a mishmash results in misguided advice and confused people. Ask me how I know.

@tkurki tkurki closed this Jan 25, 2026
@tkurki

tkurki commented Jan 25, 2026

Copy link
Copy Markdown
Member

Well, maybe 96% separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants