Skip to content

fix: forward string env vars to cluster.fork() so NODE_EXTRA_CA_CERTS etc. actually apply - #6156

Open
kiboook wants to merge 1 commit into
Unitech:developmentfrom
kiboook:fix/cluster-node-extra-ca-certs-v3
Open

fix: forward string env vars to cluster.fork() so NODE_EXTRA_CA_CERTS etc. actually apply#6156
kiboook wants to merge 1 commit into
Unitech:developmentfrom
kiboook:fix/cluster-node-extra-ca-certs-v3

Conversation

@kiboook

@kiboook kiboook commented Sep 9, 2026

Copy link
Copy Markdown
Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #5919
License MIT
Doc PR n/a

Fixes #5919.

God.nodeApp calls cluster.fork({pm2_env: JSON.stringify(env_copy), windowsHide: true}), so the only real env vars a cluster worker gets at boot are pm2_env and windowsHide. Everything the app itself set - NODE_EXTRA_CA_CERTS being the one people keep hitting - only shows up later, once pm2 parses pm2_env and assigns it onto process.env. That's after Node has already done its one-time TLS bootstrap read, so it's too late for anything Node only reads at startup.

Fork mode doesn't have this problem since it passes the real env through directly, which is exactly why "works in fork mode, breaks in cluster mode" is the recurring symptom in #5919.

#3117 proposed fixing this for NODE_EXTRA_CA_CERTS specifically back in 2017 but never got merged. This does the same thing but generally: every string-typed key in env_copy gets forwarded as a real env var to cluster.fork(), not just that one. Non-string values are deliberately skipped, since that's what the [object Object] leak in #6073 was about and I didn't want to reopen that.

To confirm this was actually the bug and not something else, I set up a private CA + a small HTTPS server locally and pointed NODE_EXTRA_CA_CERTS at the CA cert. Cluster mode failed with UNABLE_TO_VERIFY_LEAF_SIGNATURE - and process.env.NODE_EXTRA_CA_CERTS was correct inside the worker the whole time, which is what pointed me at the timing issue instead of a missing-value issue.

Added test/programmatic/issue_5919_node_extra_ca_certs.mocha.js doing the same thing (private CA generated on the fly, real HTTPS request from inside a cluster worker). It fails on master and passes with this patch. Ran it alongside issue_6073_object_env, cluster.mocha.js, filter_env.mocha.js and env_switching.js and all still pass.

@kiboook
kiboook changed the base branch from master to development September 9, 2026 11:11
… etc. actually apply

cluster.fork() was only called with {pm2_env, windowsHide}, so none of
the app's own env vars exist as real env vars in the worker at boot
time - they only get set later, after pm2_env is parsed. That's too
late for anything Node reads once during TLS bootstrap, NODE_EXTRA_CA_CERTS
being the most common case people run into with a private CA.

Fixes Unitech#5919. A narrow fix for just this one var was proposed back in
string-typed key in env_copy gets forwarded as a real env var too,
alongside pm2_env. Non-string values are skipped on purpose, that's
what pm2_env/[object Object] leak issue Unitech#6073 was about.

Reproduced locally with a private CA + a small HTTPS server: cluster
mode failed with UNABLE_TO_VERIFY_LEAF_SIGNATURE even though
process.env.NODE_EXTRA_CA_CERTS was correctly set inside the worker,
which confirms it's a timing issue and not a missing value. Added
test/programmatic/issue_5919_node_extra_ca_certs.mocha.js, which fails
without this patch and passes with it. Existing cluster/env tests
(including issue_6073) still pass.
@kiboook
kiboook force-pushed the fix/cluster-node-extra-ca-certs-v3 branch from adb6236 to 8c440a1 Compare September 9, 2026 11:16
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.

PM2 Cluster Mode does not work with NODE_EXTRA_CA_CERTS certificates

1 participant