René's URL Explorer Experiment


Title: Not a Node bug: "bad record mac" at end of stream — proxy stack injects an extra TLS record · Issue #66001 · nodejs/node · GitHub

Open Graph Title: Not a Node bug: "bad record mac" at end of stream — proxy stack injects an extra TLS record · Issue #66001 · nodejs/node

X Title: Not a Node bug: "bad record mac" at end of stream — proxy stack injects an extra TLS record · Issue #66001 · nodejs/node

Description: Version v24.21.0; Also reproduces on v20.20.2 - see the runtime matrix under Additional information. Platform Windows: Microsoft Windows NT 10.0.26200.0, x64 Linux: Ubuntu-24.04 WSL2 guest on the same host, x64 --- Windows: Microsoft Win...

Open Graph Description: Version v24.21.0; Also reproduces on v20.20.2 - see the runtime matrix under Additional information. Platform Windows: Microsoft Windows NT 10.0.26200.0, x64 Linux: Ubuntu-24.04 WSL2 guest on the s...

X Description: Version v24.21.0; Also reproduces on v20.20.2 - see the runtime matrix under Additional information. Platform Windows: Microsoft Windows NT 10.0.26200.0, x64 Linux: Ubuntu-24.04 WSL2 guest on the s...

Opengraph URL: https://github.com/nodejs/node/issues/66001

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Not a Node bug: \"bad record mac\" at end of stream — proxy stack injects an extra TLS record","articleBody":"### Version\n\nv24.21.0; Also reproduces on `v20.20.2` - see the runtime matrix under Additional information.\n\n### Platform\n\n```text\nWindows: Microsoft Windows NT 10.0.26200.0, x64\nLinux:   Ubuntu-24.04 WSL2 guest on the same host, x64\n---\nWindows: Microsoft Windows NT 10.0.19045.0, x64\n```\n\n### Subsystem\n\n`tls` - the failure is in the TLS record read path. `zlib` is the trigger (the backpressure shape) and `http` is the layer that masks the error, but neither is where the fault is.\n\n### What steps will reproduce the bug?\n\nAn HTTPS response is piped through a `node:zlib` stream that applies backpressure to the\nresponse, with the connection going through an HTTP CONNECT proxy:\n\n```js\nconst res = await get(url);                  // HTTPS through a CONNECT tunnel\nawait pipeline(\n  res,\n  countBytes,                                // plain Transform\n  zlib.createZstdDecompress(),               // or createGzip() - both reproduce\n  countBytes2,\n  slowSink,                                  // anything that lags the consumer\n  fileOrNullSink\n);\n```\n\nRequirements, each with a control that turns it off:\n\n- The body must be large enough to reach steady state (~80 MB observed; smaller was not\n  characterised).\n- The zlib stream must be **directly downstream of `res`**. Moving a lagging plain `Transform`\n  in front of the zlib stream does not reproduce.\n- The consumer downstream of zlib must lag enough to backpressure the response. Packet capture\n  shows repeated `TCP Zero Window` segments on the client's receive side. Without the artificial\n  lag the failure still occurs, but intermittently; the lag only raises the trigger rate to about\n  100%.\n- The relay in front of the client must be an HTTP CONNECT proxy; see \"How often does it\n  reproduce\".\n\nSelf-contained script (Node standard library only, no third-party dependencies). It needs Node\n>= 22.15 for `zlib.createZstdDecompress`; substitute `createGzip()` on older versions:\n\n```js\n// repro.mjs\n//\n//   node repro.mjs --url \u003clarge HTTPS artifact, ~80 MB or more> --proxy \u003chttp://host:port>\n//   node repro.mjs --url \u003csame> --proxy \u003csame> --decode none      # control: no decompressor\n//   node repro.mjs --url \u003csame> --proxy \u003csame> --drain-first      # control: no backpressure\nimport http from 'node:http';\nimport https from 'node:https';\nimport tls from 'node:tls';\nimport zlib from 'node:zlib';\nimport { Readable, Transform, Writable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { parseArgs } from 'node:util';\n\nconst { values } = parseArgs({ options: {\n  url: { type: 'string' },\n  proxy: { type: 'string' },\n  decode: { type: 'string', default: 'zstd' },\n  lag: { type: 'string', default: '100' },\n  'drain-first': { type: 'boolean', default: false }\n} });\n\nconst target = new URL(values.url);\nconst proxy = new URL(values.proxy);\n\nasync function connect() {\n  const req = http.request({\n    host: proxy.hostname,\n    port: Number(proxy.port || 80),\n    method: 'CONNECT',\n    path: `${target.hostname}:${target.port || 443}`\n  });\n  req.end();\n  return new Promise((resolve, reject) => {\n    req.once('connect', (r, socket) =>\n      r.statusCode === 200 ? resolve(socket) : reject(new Error(`CONNECT ${r.statusCode}`)));\n    req.once('error', reject);\n  });\n}\n\nconst tunnel = await connect();\nconst res = await new Promise((resolve, reject) => {\n  const req = https.request({\n    host: target.hostname,\n    port: Number(target.port || 443),\n    path: target.pathname + target.search,\n    createConnection: () => tls.connect({ socket: tunnel, servername: target.hostname })\n  }, resolve);\n  req.once('error', reject);\n  req.end();\n});\n\nlet wire = 0;\nconst count = new Transform({ transform(c, _e, cb) { wire += c.length; cb(null, c); } });\n\n// Consumer lag: hold the callback for a timer tick every 1 MB. This is what makes\n// the response backpressure.\nconst lagMs = Number(values.lag);\nlet acc = 0;\nconst lag = new Transform({\n  highWaterMark: 4194304,\n  transform(c, _e, cb) {\n    acc += c.length;\n    if (acc \u003c 1048576) return cb(null, c);\n    acc = 0;\n    setTimeout(() => cb(null, c), lagMs);\n  }\n});\n\nconst sink = new Writable({ highWaterMark: 4194304, write(_c, _e, cb) { cb(); } });\n\ntry {\n  if (values['drain-first']) {\n    // Control: consume the response with no backpressure, decompress afterwards.\n    const chunks = [];\n    await new Promise((resolve, reject) => {\n      res.on('data', (c) => { wire += c.length; chunks.push(c); });\n      res.once('end', resolve);\n      res.once('error', reject);\n    });\n    await pipeline(Readable.from(chunks), zlib.createZstdDecompress(), lag, sink);\n  } else {\n    const stages = values.decode === 'zstd' ? [zlib.createZstdDecompress()] : [];\n    await pipeline(res, count, ...stages, lag, sink);\n  }\n  console.log(`OK wire=${wire}`);\n} catch (err) {\n  console.log(`FAIL code=${err.code} msg=${JSON.stringify(err.message)} wire=${wire}`);\n  console.log(`res.complete=${res.complete} res.aborted=${res.aborted}` +\n    ` res.readableEnded=${res.readableEnded} res.destroyed=${res.destroyed}`);\n}\n```\n\nRun each configuration several times, and run a passing configuration in the same minute: the\nfailure is intermittent, so a single run proves nothing in either direction.\n\n\n### How often does it reproduce? Is there a required condition?\n\nWith the consumer lag in place, essentially every run fails - the transfer stops at\n99.76% - 99.96% of the declared body. Without the lag it fails intermittently, which is why\nevery measurement in this report was paired with a same-minute positive control.\n\nThree conditions must hold at once:\n\n1. A `node:zlib` stream directly downstream of the response.\n2. Backpressure from the consumer reaching the response through that zlib stream.\n3. A relay that re-chunks the stream with a particular **write-size distribution** - see\n   Additional information.\n\nCondition 3 is the one that is **not** reproduced without a real relay. The reproduction below\nstill needs one, and this issue does not claim any specific proxy is required - only that a\nthird-party relay is currently the only thing that triggers it dependably on this path. A fully\nlocal rig (self-signed TLS origin on loopback) never reproduces.\n\n### What is the expected behavior? Why is that the expected behavior?\n\nA complete, correctly transmitted TLS stream must decrypt regardless of how the application\napplies backpressure. Backpressure is an application-level property and cannot change the bytes\non the wire - and in this case the bytes were proven intact offline (see Additional\ninformation). Failing to decrypt them is a defect in the reading side.\n\nSecondarily, the HTTP client should not translate a TLS failure into `aborted` /\n`ECONNRESET`: that rewrites the root cause into a network error and is why applications\ndownstream blame the proxy or the network.\n\n### What do you see instead?\n\n```\nERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC\nerror:0A000119:SSL routines:tls_get_more_records:decryption failed or bad record mac\n```\n\nfollowed by a fatal `bad_record_mac` alert being sent to the peer.\n\nEvent order, from listeners attached to every object in the chain:\n\n```\n21.153 tlsSocket.error  ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC\n21.153 rawSocket.close\n21.153 tlsSocket.close\n21.154 res.aborted\n21.154 res.error        ECONNRESET: aborted\n21.155 (pipeline tears down every downstream stage)\n```\n\nThe TLS error is first; everything after it is a consequence.\n\nWhat the application sees, because Node's HTTP client observes the socket closing while\n`res.complete === false` and replaces the error with `connResetException('aborted')`:\n\n```\ncode=ECONNRESET  msg=\"aborted\"\nres.complete=false  res.aborted=true  res.readableEnded=false  res.destroyed=true\n```\n\n### Additional information\n\n### The ciphertext on the wire is intact\n\nThe inner TLS stream (the CONNECT tunnel on loopback) was captured in full, and the session keys\nwere exported from the failing run with `--tls-keylog`. Decrypting the capture offline with\nthose keys: **8,491 application-data records, 80,603,843 bytes, zero decryption failures**. The\nsame bytes, processed in-process by the running Node client at the same moment, produced a MAC\nfailure.\n\nCommands used:\n\n```\n# capture the inner TLS stream, full packets\ntshark -i \u003cloopback interface> -f \"tcp port \u003cproxy port>\" -w \u003ccapture> -a duration:70\n\n# export session keys from the failing run\nnode --tls-keylog=\u003ckeylog> repro.mjs ...\n\n# any record that failed to decrypt would appear in expert info\ntshark -r \u003ccapture> -o tls.keylog_file:\u003ckeylog> -d tcp.port==\u003cproxy port>,http \\\n       -Y \"tcp.stream==\u003cn> && _ws.expert\" -T fields -e frame.number -e _ws.expert.message\n\n# and the decrypted application-data volume must match expectations\ntshark -r \u003ccapture> -o tls.keylog_file:\u003ckeylog> -d tcp.port==\u003cproxy port>,http \\\n       -Y \"tcp.stream==\u003cn> && tls.record.content_type==23\" -T fields -e tls.record.length\n```\n\n`--export-objects http,\u003cdir>` is not usable here: it silently exports nothing when the response\nbody is large.\n\n### Platform / TLS-library / runtime matrix\n\nSame proxy, same origin, same artifact, comparable consumer lag. Every row was run with a\nsame-minute positive control, because the failure is intermittent. The percentage is where the\ntransfer stopped, not a failure rate.\n\n| Runtime | TLS library | Event library | Platform | Result (stop point, % of declared body) |\n|---|---|---|---|---|\n| Node 24.21.0 | OpenSSL 3.5.8 (bundled) | libuv 1.52.1 | Windows 11 x64 | **FAIL** 99.963% |\n| Node 24.21.0 | OpenSSL 3.5.8 (bundled) | libuv 1.52.1 | Linux (WSL2) | **FAIL** 99.760% |\n| Node 20.20.2 | OpenSSL 3.0.19 (bundled) | libuv 1.46.0 | Linux (WSL2) | **FAIL** 99.963% |\n| Python 3.12.3 | OpenSSL 3.0.13 (system) | - | Linux (WSL2) | **OK**, correct hash |\n\nThe two Node failures start with the same error text but go through different OpenSSL internals:\n\n```\nNode 24 / 3.5.8    tls_get_more_records   tls_common.c\nNode 20 / 3.0.19   ssl3_get_record        ssl3_record.c\n```\n\nSo: not platform-specific (the Windows overlapped-I/O read path is out), and not an OpenSSL\nversion regression (3.0.19 and 3.5.8 both fail, via different code). The difference that matters\nis the runtime - same OpenSSL major, Python completes and Node does not.\n\n### Mechanism hypothesis (narrowed, not proven)\n\nPython lets OpenSSL read the socket itself; Node pushes TCP chunks into a memory BIO and lets\nOpenSSL read from there. If Node reuses, truncates or misaligns the buffer it feeds to that BIO\nacross a backpressure pause/resume, the result is exactly `bad record mac`. This fits every known\ncondition: needs backpressure (for the pause/resume), needs a relay (so records straddle read\nboundaries), platform-independent, OpenSSL-version-independent.\n\nCaveat: Python's read shape (blocking `read` plus sleeps) is not identical to Node's stream\nbackpressure, so its pass shows the failure is not universal to TLS clients under backpressure -\nit does not prove that no other read shape can drive OpenSSL into this.\n\n### The relay's write-size sequence\n\nFailing and passing paths were compared by recording the size of every downstream write the relay\nmade:\n\n| | failing relay | passing relay (`ssh -L`) |\n|---|---|---|\n| writes | 1461 | 1295 |\n| smallest write | 616 | 2608 |\n| writes `\u003c= 16 KB` | **14.0%** | 2.4% |\n| writes `\u003c= 4 KB` | **6.6%** | 0.4% |\n| common small sizes | 2824 / 5648 / 8472 (multiples of 1412) | rare |\n| inter-arrival p50 / p95 | 0.152 / 16.95 ms | 0.175 / 12.56 ms |\n\nInter-arrival timing is nearly identical; the measured difference is concentrated in write\nsizes. The failing relay is a local HTTP CONNECT proxy (mihomo) forwarding to a remote egress;\nthe passing one is an `ssh -L` tunnel to the same egress host.\n\nReplaying the recorded sequence through a purpose-written CONNECT proxy on the passing path does\nreproduce the failure - but only sometimes, so write sizes are **a** relevant characteristic, not\na sufficient one:\n\n| Synthesised | Result |\n|---|---|\n| Recorded write-size sequence | 2 failures out of 7 attempts |\n| Write sizes **plus** recorded inter-arrival gaps | 0 out of 4 |\n| Either of the above **plus** unbounded read-ahead | 0 out of 2 |\n| Local TLS origin forced to emit small (2824-byte) records | 0 out of 1 |\n| Uniform chunking at 16384 / 4096 / 1412 bytes, with `TCP_NODELAY` | 0 out of 3 |\n\nThe recorded median inter-arrival gap is **0.152 ms**. JavaScript timers cannot reproduce\nsub-millisecond arrival structure, so anything below 1 ms degrades to `setImmediate`. That is a\ntooling ceiling here, not a matter of trying more patterns; going further would need\npacket-level shaping or pcap replay.\n\nWhat these attempts do establish is that no data tampering is involved - a relay that merely\nre-chunks a correct byte stream can trigger it at least sometimes.\n\n### The stop point\n\nThe failure always lands very close to the end, and repeatedly on exactly the same offset -\nincluding across two **different** upstream egress servers in different regions running\ndifferent proxy-server implementations:\n\n```\nbytes delivered into the pipeline: 80,428,448\nbytes emitted by the decompressor: 222,453,760\n```\n\nAcross all runs the stop point takes a small number of discrete values in the range\n99.76% - 99.96% of the body rather than a continuum. That suggests fixed client-side buffer\nboundaries rather than anything network-timing-dependent, but the value is not constant, so it\nshould not be read as a single magic offset.\n\n### Ruled out\n\nEach item has a controlled experiment behind it.\n\n| Hypothesis | Verdict | Control |\n|---|---|---|\n| The proxy corrupts bytes | **No** | Offline decryption of the captured ciphertext with `--tls-keylog` keys: all records decrypt, no failures. Same trigger conditions over **plain HTTP** at comparable throughput: 104,857,600 bytes, SHA-256 identical to baseline, while a same-minute HTTPS positive control failed. Inserting a purpose-written proxy in front of it does not neutralise the failure. |\n| That specific proxy is strictly required | **Unresolved** | Replaying its recorded write-size sequence through a purpose-written proxy on a path it is not part of reproduced the failure 2/7. Enough to show no tampering is needed; not enough to call it unnecessary. |\n| Windows-specific I/O read path | **No** | Same build reproduces on Linux. |\n| OpenSSL version regression | **No** | OpenSSL 3.0.19 and 3.5.8 both reproduce, through different internal code paths. |\n| TLS records being small | **No** | A local origin forced to emit 2824-byte records does not reproduce. |\n| Data expansion by decompression | **No** | `createGzip()` on already-compressed input (in ~= out) reproduces. |\n| Slow consumer alone | **No** | A plain `Transform` with the same total lag and the same backpressure completes. |\n| Per-chunk async deferral | **No** | A `Transform` deferring every chunk via `setImmediate`, same total lag, completes. |\n| libuv threadpool contention | **No** | `UV_THREADPOOL_SIZE` of 1 and of 32 both reproduce. |\n| Backpressure on `res` | **Required** | Draining the response fully into memory first, then decompressing with the same lag downstream, completes with a correct hash. |\n| A `zlib` stream in the chain | **Required** | Same lag and same backpressure; the only difference is whether that stage is `zlib`. |\n| Ordering | **Matters** | Putting the lagging plain `Transform` *before* the zlib stream does not reproduce. Backpressure must reach `res` through the zlib stream. |\n| Going through the proxy | **Required** | The identical configuration over an `ssh -L` tunnel to the same egress host completes with a correct hash. |\n\n### Workaround\n\nDo not place a streaming decompressor directly downstream of the HTTP response. Drain the\nresponse without backpressure, then decompress. Verified on the same path with the same\ndecompressor and the same total lag: correct output hash.\n\n### Not yet tested\n\n- macOS\n- Bare-metal Linux (the Linux result above is from WSL2; a positive there is still decisive, but\n  the kernel is a vendor fork behind a virtual NIC)\n- A non-OpenSSL runtime such as Go, which would tell whether any TLS implementation can be driven\n  into this by the same relay\n- HTTP/2 (the failing path is HTTP/1.1 inside the tunnel)\n- Which relay characteristic is actually required (see the synthetic-relay table above)\n\n---\n\nAI assistance: the investigation, experiment design and write-up of this report were done\nwith Claude (Opus 5). All runs were executed on the reporting host against the real path;\nevery number in this report is measured on that host, not estimated.\n","author":{"url":"https://github.com/yx64","@type":"Person","name":"yx64"},"datePublished":"2026-09-12T15:43:40Z","url":"https://github.com/nodejs/node/issues/66001"}

react-profiling0
react-import-mapreact,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf
route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:aa69830a-8fa2-29f0-1a76-d0e2c59a60fc
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-idB0FE:182799:AA5062:E2FB97:6AED362D
html-safe-nonced74fd614c8b3abc024aaa3aa0de9ef40ab3dcf4b319e724184f3f46db7bb3a7e
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCMEZFOjE4Mjc5OTpBQTUwNjI6RTJGQjk3OjZBRUQzNjJEIiwidmlzaXRvcl9pZCI6IjE4MDc3NTQ0MTU3MDU0MzE0OSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmaca9a2950a7a669569631b87909b9fe7823e6ed9c0344448c5d84883434fe29760
hovercard-subject-tagissue:5434309463
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/66001/issue_layout
twitter:imagehttps://opengraph.githubassets.com/e66f6e99da50dbeaf275bbcfd7652f95e463ccd1d7f01946d733b616731fa501/nodejs/node/issues/66001
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/e66f6e99da50dbeaf275bbcfd7652f95e463ccd1d7f01946d733b616731fa501/nodejs/node/issues/66001
og:image:altVersion v24.21.0; Also reproduces on v20.20.2 - see the runtime matrix under Additional information. Platform Windows: Microsoft Windows NT 10.0.26200.0, x64 Linux: Ubuntu-24.04 WSL2 guest on the s...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernameyx64
hostnamegithub.com
expected-hostnamegithub.com
None26c92a9388ddfad3fa88d132b5d5f0b4747030233dcc4e5efb05f1cbae152184
turbo-cache-controlno-preview
go-importgithub.com/nodejs/node git https://github.com/nodejs/node.git
octolytics-dimension-user_id9950313
octolytics-dimension-user_loginnodejs
octolytics-dimension-repository_id27193779
octolytics-dimension-repository_nwonodejs/node
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id27193779
octolytics-dimension-repository_network_root_nwonodejs/node
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
releasec629ad99c254d306375fc8354d04321c2c362236
ui-targetfull
theme-color#1e2327
color-schemelight dark
react-app-nameissues

Links:

Skip to contenthttps://github.com/nodejs/node/issues/66001#start-of-content
https://github.com/
Sign inhttps://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fissues%2F66001
GitHubRepository hosting, code review, and collaborationhttps://github.com/platform
CopilotAI coding agent for tasks, projects, and automated workhttps://github.com/features/copilot
ActionsCI/CD and automationhttps://github.com/features/actions
Code QualityQuality analysis, fixes, and enforcementhttps://github.com/features/code-quality
CodespacesCloud development environmentshttps://github.com/features/codespaces
Code SecurityVulnerability detection and remediationhttps://github.com/security/advanced-security/code-security
Secret ProtectionSecret scanning and leak preventionhttps://github.com/security/advanced-security/secret-protection
All Featureshttps://github.com/features
Documentationhttps://docs.github.com/en
Traininghttps://learn.github.com/skills
Certificationshttps://learn.github.com/credentials
Build with Copilothttps://github.com/features/ai
Customize Copilothttps://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-copilot-overview
Integrationshttps://github.com/marketplace
Trending reposhttps://github.com/trending
GitHub Sponsorshttps://github.com/open-source/sponsors
Developer articleshttps://github.com/resources/articles
ChangelogYour source for the latest features, improvements, and fixes across GitHub products, all in one place.https://github.blog/changelog/
Enterpriseshttps://github.com/enterprise
Teamhttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
See all industrieshttps://github.com/solutions/industry
Why GitHubhttps://github.com/why-github
Customer Storieshttps://github.com/customer-stories
Business insightshttps://github.com/solutions/executive-insights
Trust Centerhttps://github.com/trust-center
GitHub Advanced SecurityEnterprise-grade code securityhttps://github.com/security/advanced-security
Copilot for businessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Documentationhttps://docs.github.com/en
Resource centerhttps://github.com/resources
Bloghttps://github.blog/
Events & webinarshttps://github.com/resources/events
Community Forumhttps://github.com/orgs/community/discussions
Customer Storieshttps://github.com/customer-stories
Integrationshttps://github.com/marketplace
Customer supporthttps://help.github.com/
Traininghttps://learn.github.com/skills
GitHub Statushttps://www.githubstatus.com/
Abouthttps://github.com/about
Partnershttps://github.com/partners
Changeloghttps://github.blog/changelog/
GitHub UniverseThe event for developers, by developers — talks, workshops, and what’s next for GitHub.https://githubuniverse.com/
Pricinghttps://github.com/pricing
Sign inhttps://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fissues%2F66001
Sign uphttps://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=nodejs%2Fnode
Reloadhttps://github.com/nodejs/node/issues/66001
Reloadhttps://github.com/nodejs/node/issues/66001
Reloadhttps://github.com/nodejs/node/issues/66001
nodejshttps://github.com/nodejs
nodehttps://github.com/nodejs/node
Codehttps://github.com/nodejs/node
Issues656 (656)https://github.com/nodejs/node/issues
Pull requests665 (665)https://github.com/nodejs/node/pulls
Actionshttps://github.com/nodejs/node/actions
Projectshttps://github.com/nodejs/node/projects
Security and qualityhttps://github.com/nodejs/node/security
Insightshttps://github.com/nodejs/node/pulse
https://github.com/nodejs/node
New issuehttps://github.com/login?return_to=https://github.com/nodejs/node/issues/66001
New issuehttps://github.com/login?return_to=https://github.com/nodejs/node/issues/66001
Not a Node bug: "bad record mac" at end of stream — proxy stack injects an extra TLS recordhttps://github.com/nodejs/node/issues/66001#top
streamIssues and PRs related to Node.js streams.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22stream%22
tlsIssues and PRs related to the tls subsystem.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22tls%22
zlibIssues and PRs related to the zlib module and its compression dependencies.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22zlib%22
https://github.com/yx64
yx64https://github.com/yx64
on Sep 12, 2026https://github.com/nodejs/node/issues/66001#issue-5434309463
inoway46https://github.com/inoway46
tlsIssues and PRs related to the tls subsystem.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22tls%22
streamIssues and PRs related to Node.js streams.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22stream%22
zlibIssues and PRs related to the zlib module and its compression dependencies.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22zlib%22
on Sep 14, 2026https://github.com/nodejs/node/issues/66001#event-31105898011
XadillaXhttps://github.com/XadillaX
on Sep 16, 2026https://github.com/nodejs/node/issues/66001#event-31244058320
http: preserve socket errors as response error causeshttps://github.com/XadillaX/node/commit/cd91d44b40732760af6baa3980f89a117ae870c1
cd91d44https://github.com/XadillaX/node/commit/cd91d44b40732760af6baa3980f89a117ae870c1
yx64https://github.com/yx64
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#event-31476199384
https://github.com/yx64
yx64https://github.com/yx64
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#issuecomment-5748778831
#66061https://github.com/nodejs/node/pull/66061
@XadillaXhttps://github.com/XadillaX
https://github.com/yx64
yx64https://github.com/yx64
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#issuecomment-5749769374
@XadillaXhttps://github.com/XadillaX
#66061https://github.com/nodejs/node/pull/66061
@XadillaXhttps://github.com/XadillaX
yx64https://github.com/yx64
completedhttps://github.com/nodejs/node/issues?q=is%3Aissue%20state%3Aclosed%20archived%3Afalse%20reason%3Acompleted
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#event-31480500133
yx64https://github.com/yx64
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#event-31480617660
yx64https://github.com/yx64
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#event-31480777253
yx64https://github.com/yx64
not plannedhttps://github.com/nodejs/node/issues?q=is%3Aissue%20state%3Aclosed%20archived%3Afalse%20reason%3Anot-planned
on Sep 20, 2026https://github.com/nodejs/node/issues/66001#event-31480817513
panvahttps://github.com/panva
on Sep 25, 2026https://github.com/nodejs/node/issues/66001#event-31860373117
http: preserve socket errors as response error causeshttps://github.com/nodejs/node/commit/5ebf690dcfa6ace3d0c2704df975b9f96cd6f18c
5ebf690https://github.com/nodejs/node/commit/5ebf690dcfa6ace3d0c2704df975b9f96cd6f18c
aduh95https://github.com/aduh95
on Sep 27, 2026https://github.com/nodejs/node/issues/66001#event-31936995562
http: preserve socket errors as response error causeshttps://github.com/nodejs/node/commit/8a39885f8593b89f8d46e0d21b09d5dca5be27b7
8a39885https://github.com/nodejs/node/commit/8a39885f8593b89f8d46e0d21b09d5dca5be27b7
HoonDongKanghttps://github.com/HoonDongKang
on Sep 28, 2026https://github.com/nodejs/node/issues/66001#event-31971104478
http: preserve socket errors as response error causeshttps://github.com/HoonDongKang/node/commit/5bbd2c79e547ca88e9907cdf772aaf807f22fc4f
5bbd2c7https://github.com/HoonDongKang/node/commit/5bbd2c79e547ca88e9907cdf772aaf807f22fc4f
aduh95https://github.com/aduh95
on Sep 28, 2026https://github.com/nodejs/node/issues/66001#event-32031887621
http: preserve socket errors as response error causeshttps://github.com/nodejs/node/commit/ab93a3d51bdce79c445bbeea450e756bde83a2b4
ab93a3dhttps://github.com/nodejs/node/commit/ab93a3d51bdce79c445bbeea450e756bde83a2b4
aduh95https://github.com/aduh95
on Oct 23, 2026https://github.com/nodejs/node/issues/66001#event-34094377141
http: preserve socket errors as response error causeshttps://github.com/nodejs/node/commit/c52d34532e0be584b3b8621d19c9e019b4f5000e
c52d345https://github.com/nodejs/node/commit/c52d34532e0be584b3b8621d19c9e019b4f5000e
http: preserve socket errors as response error causeshttps://github.com/nodejs/node/commit/c5669fb741b2eb869b85c1d5ecd6b127f294f270
c5669fbhttps://github.com/nodejs/node/commit/c5669fb741b2eb869b85c1d5ecd6b127f294f270
Sign up for freehttps://github.com/signup?return_to=https://github.com/nodejs/node/issues/66001
Sign in to commenthttps://github.com/login?return_to=https://github.com/nodejs/node/issues/66001
streamIssues and PRs related to Node.js streams.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22stream%22
tlsIssues and PRs related to the tls subsystem.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22tls%22
zlibIssues and PRs related to the zlib module and its compression dependencies.https://github.com/nodejs/node/issues?q=state%3Aopen%20label%3A%22zlib%22
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.