Repository navigation
Description
Describe the bug
On Windows, asset fingerprinting throws EINVAL: invalid argument, open for every file it hashes when running on Node.js 26.8.0 or newer. The failure originates in aws-cdk-lib/core/lib/fs/fingerprint.js, in contentFingerprintMiss(), which opens files with the flag combination fs.constants.O_DSYNC | fs.constants.O_RDONLY | fs.constants.O_SYNC.
Before Node.js 26.8.0, O_SYNC and O_DSYNC were undefined on Windows, so this expression coerced to 0 (effectively O_RDONLY) and the open succeeded. Node.js 26.8.0 (nodejs/node#64707) defined these constants on Windows as real, non-zero bits. The unchanged CDK line now passes both O_SYNC and O_DSYNC set simultaneously to fs.openSync. libuv's Windows fs__open() explicitly rejects that combination and returns UV_EINVAL / Win32 ERROR_INVALID_PARAMETER.
This breaks CDK synth / asset staging on Windows with Node.js >= 26.8.0.
Regression Issue
- Select this option if this issue appears to be a regression.
This is a regression triggered by the Node.js runtime version (26.7.0 works, 26.8.0/26.8.1 fail on the identical aws-cdk-lib code).
Last Known Working CDK Library Version
aws-cdk-lib 2.244.0 works on Node.js <= 26.7.0. The aws-cdk-lib code is unchanged across the break — the regression is gated purely on the Node.js runtime version.
Expected Behavior
Asset fingerprinting / synth should open files for read-hashing successfully on Windows regardless of Node.js patch version. A read-only content hash has no need for O_SYNC/O_DSYNC (write-through) semantics, so the open should not fail with EINVAL.
Current Behavior
On Windows + Node.js >= 26.8.0, every file hashed during asset staging throws:
Error: EINVAL: invalid argument, open 'D:\...\index.js'
at Object.openSync (node:fs:779:18)
at contentFingerprintMiss (node_modules/aws-cdk-lib/core/lib/fs/fingerprint.js)
at contentFingerprint (node_modules/aws-cdk-lib/core/lib/fs/fingerprint.js)
at _processFileOrDirectory (node_modules/aws-cdk-lib/core/lib/fs/fingerprint.js)
at FileSystem.fingerprint (node_modules/aws-cdk-lib/core/lib/fs/index.js)
at AssetStaging.calculateHash (node_modules/aws-cdk-lib/core/lib/asset-staging.js)
{ errno: -4071, code: 'EINVAL', syscall: 'open', path: '...' }
The offending call in fingerprint.js contentFingerprintMiss():
const fd = fs.openSync(file, fs.constants.O_DSYNC | fs.constants.O_RDONLY | fs.constants.O_SYNC);Reproduction Steps
On a Windows machine with Node.js >= 26.8.0, this self-contained snippet reproduces the exact failure against the same code path:
// repro.js — run with `node repro.js` on Windows under Node >= 26.8.0
const fs = require('fs');
const os = require('os');
const path = require('path');
const file = path.join(os.tmpdir(), 'cdk-einval-repro.txt');
fs.writeFileSync(file, 'hello');
// Exactly what aws-cdk-lib/core/lib/fs/fingerprint.js contentFingerprintMiss() does:
const flags = fs.constants.O_DSYNC | fs.constants.O_RDONLY | fs.constants.O_SYNC;
const fd = fs.openSync(file, flags); // throws EINVAL on Windows + Node >= 26.8.0
fs.closeSync(fd);
console.log('opened OK');Alternatively, cdk synth of any stack containing a Lambda/asset on Windows + Node.js 26.8.0 triggers it via AssetStaging.calculateHash.
Possible Solution
In core/lib/fs/fingerprint.js contentFingerprintMiss(), drop the O_SYNC/O_DSYNC flags — they request write-through/sync semantics that are meaningless for a read-only hash — and open read-only:
// before
const fd = fs.openSync(file, fs.constants.O_DSYNC | fs.constants.O_RDONLY | fs.constants.O_SYNC);
// after
const fd = fs.openSync(file, fs.constants.O_RDONLY);This is platform-agnostic and removes flags that never served a purpose for hashing. (Separately, libuv/Node arguably should treat O_SYNC+O_DSYNC as idempotent on Windows like POSIX; a companion nodejs/node issue against #64707 may be warranted, but the CDK-side change fully resolves the user-facing break.)
Additional Information/Context
Verified root-cause chain:
- Node.js <= 26.7.0:
fs.constants.O_SYNC/O_DSYNCareundefinedon Windows →undefined | 0 | undefinedcoerces to0→ benignO_RDONLYopen. Works. - src: define O_SYNC, O_DSYNC and O_DIRECT on Windows nodejs/node#64707 ("src: define O_SYNC, O_DSYNC and O_DIRECT on Windows", shipped in v26.8.0) defines them on Windows as real bits:
O_SYNC=0x08000000,O_DSYNC=0x04000000. - CDK's unchanged line now computes
flags = 0x0C000000(both sync bits set) and passes them tofs.openSync. - libuv Windows
fs__open()(src/win/fs.c):switch (flags & (UV_FS_O_DSYNC | UV_FS_O_SYNC))handles0/O_DSYNC-alone /O_SYNC-alone, but BOTH bits set falls through todefault: goto einval;→UV_EINVAL/ERROR_INVALID_PARAMETER. - Surfaces as
EINVAL … errno -4071 … syscall 'open'. - POSIX kernels treat both-sync-bits as harmless, so Linux/macOS are unaffected.
AWS CDK Library version (aws-cdk-lib)
2.244.0
AWS CDK CLI version
2.1113.0
Node.js Version
Fails on 26.8.0 and 26.8.1; last known working 26.7.0
OS
Windows (GitHub Actions windows-2025 runner; expected on Windows generally)
Language
TypeScript
Other information
Suspected trigger: nodejs/node#64707 (companion #64775 exposes further Windows fs flags). aws-cdk-lib is unchanged across the regression — the break is gated purely on the Node.js runtime version.
Activity
pahud commentedon Aug 28, 2026
Hi @soberm,
This is a good catch, and the root-cause analysis matches the affected
2.244.0artifact. I wasn't able to reproduce the Windows-onlyEINVALlocally because my available environment is macOS; the exact snippet opens successfully there, as expected. I did verify that published2.244.0passes both sync flags and that Windows libuv rejects that combination once Node.js exposes them.The good news is that this was already fixed by #37802 before Node.js 26.8.0 was released.
contentFingerprintMiss()now opens files withO_RDONLYonly, and the change first shipped in[email protected]:aws-cdk/packages/aws-cdk-lib/core/lib/fs/fingerprint.ts
Lines 192 to 196 in b871018
https://github.com/aws/aws-cdk/releases/tag/v2.254.0
Could you try upgrading
aws-cdk-libto2.254.0or newer? The current latest release,2.267.0, also contains this fix. If it still reproduces after upgrading, please share the resolvedaws-cdk-libversion and updated stack trace and we can investigate further.Since the implementation is already fixed, no additional code change appears necessary. If you'd like to contribute, a focused regression test asserting that fingerprinting passes only
O_RDONLYtofs.openSync()would still be welcome.github-actions commentedon Aug 30, 2026
This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
chore: bump aws-cdk-lib to ^2.254.0 (fixes Windows Node EINVAL) (#3317)