Quick fix
# One-liner: temporary compatibility — enable the legacy provider so OpenSSL serves MD4 again
NODE_OPTIONS=--openssl-legacy-provider npm run build
Only as a transition; upgrade the build tool long-term.
What you will run into
Running an old project on a new Node version (webpack 4 family, e.g. legacy create-react-app / vue-cli projects) fails immediately at build/start: Error: error:0308010C:digital envelope routines::unsupported.
Zero seconds into the build, no business code changed; switching to the project's required old Node (e.g. 16.15.0) works. It's not the project code — it's the compatibility gap between an old build tool and a new runtime.
Why this happens
Node ≥17 links against OpenSSL 3, which moved MD4 to the legacy provider (not loaded by default); webpack <5 uses crypto.createHash('md4') by default for module/chunk hashing, which throws digital envelope routines::unsupported on call.
You hit this most often after a Node major upgrade.
digital envelope routines::unsupported is OpenSSL 3's provider mechanism: OpenSSL 3 moved weak algorithms like MD4/MD5 into the legacy provider, which is not loaded by default;
Node ≥17 links OpenSSL 3, and webpack <5 hashes modules/chunks with crypto.createHash('md4') — the algorithm does not exist in the default provider, so the call throws.
This is not a business-code bug; it is a "toolchain version combination" issue: after a major Node upgrade the underlying OpenSSL changed, and old build tools changed behavior.
Deterministic takeaway: after upgrading Node, an old project failing to build with this error = check whether the bundler uses md4 (webpack config output.hashFunction);
two correct paths — upgrade webpack (≥5 defaults to safer algorithms) or explicitly set output.hashFunction: 'sha256' (works on webpack <5);
NODE_OPTIONS=--openssl-legacy-provider is a temporary escape hatch that reloads the legacy provider — it gets you moving but regresses to weak algorithms; use it only for legacy projects that cannot be upgraded;
fixed diagnostic: createHash/md4 in the stack trace confirms it.
Step by step
1. Long-term fix: upgrade the build tool — Required
Upgrade webpack to ≥5 (5.61+ has a wasm hash fallback and no longer depends on OpenSSL MD4); follow the official upgrade scripts for create-react-app/vue-cli projects (npm i -D webpack@5 / npx create-react-app@latest etc.).
2. Temporary compatibility (fastest) — Required
NODE_OPTIONS=--openssl-legacy-provider npm run build
Or write it into .env (legacy CRA projects read it): echo NODE_OPTIONS=--openssl-legacy-provider >> .env. Note: Node 17.0–17.2 doesn't allow this flag in NODE_OPTIONS; use the CLI argument node --openssl-legacy-provider or switch Node versions.
The legacy provider is less secure than default; transition only.
3. Switch Node versions (the article's approach) — Required
nvm use 16.15.0
Switching to the project's locked old version works — a symptom fix that hides the "toolchain too old" root cause; upgrading is still recommended long-term.
How to confirm it works
md4 works (measured output shape):
NODE_OPTIONS=--openssl-legacy-provider node -e "crypto.createHash('md4').update('x').digest('hex')" → digest 866437cb... (measured)
Control group: default config createHash('md4') → error:0308010C (measured reproduction, stack matching the article verbatim); createHash('sha256') works (md4-specific problem).
Other environments
| Environment | Notes |
|---|---|
| Node ≥17 + OpenSSL 3 | md4 lives in the legacy provider, unavailable by default |
| webpack <5 | Uses md4 for hashing, always hits it |
| webpack ≥5.61 | wasm hash fallback, nothing to do |
| Node 17.0–17.2 | NODE_OPTIONS doesn't allow the flag; use the CLI argument |
| Switch Node version | nvm use old version; symptom fix |
Symptom
Running an old project (webpack 4 family, e.g. old create-react-app / vue-cli projects) with a new Node version fails immediately at build/start:
ERROR Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:101:19)
at Object.createHash (node:crypto:139:10)
Typical scene: Node 22.x locally, failure happens 0 seconds in with no business-code change; switching to the project's required lower Node (e.g. 16.15.0) works.
Cause
Node ≥17 links OpenSSL 3, which moved MD4 into the legacy provider (not loaded by default); webpack <5 hashes modules/chunks with crypto.createHash('md4') by default and throws digital envelope routines::unsupported. This is not a project-code bug but the compatibility gap between old build tools and the new runtime (you hit it right after upgrading a Node major version).
Solution
In recommended order:
- Long-term: upgrade the build tool — webpack ≥5 (5.61+ has a built-in wasm hash fallback, no OpenSSL MD4 dependency); follow the official upgrade path for create-react-app/vue-cli (
npm i -D webpack@5/npx create-react-app@latest, etc.). - Quick temporary fix: enable the legacy provider so OpenSSL provides MD4 again:
# per command
NODE_OPTIONS=--openssl-legacy-provider npm run build
# or append to .env (read by old CRA projects)
echo NODE_OPTIONS=--openssl-legacy-provider >> .env
Note: Node 17.0–17.2 reject this flag in NODE_OPTIONS; use the CLI arg node --openssl-legacy-provider or switch Node versions. The legacy provider is weaker than the default; use it only as a stopgap.
- Switch Node versions (the article's fix):
nvm use 16.15.0(the version pinned by the project) works — but it masks the outdated toolchain; upgrade long-term.
Verification Evidence
- Local repro (2026-08-29, Node v22.22.1 / npm 9.2.0 / OpenSSL 3.5.5, same generation as the article's failing env):
node -e "crypto.createHash('md4')..."→ reproducederror:0308010C:digital envelope routines::unsupportedwith a stack identical to the article (new Hash (node:internal/crypto/hash:101:19));- Control:
createHash('sha256')in the same process outputs a digest normally — proves it is md4-specific, not a broken crypto module; NODE_OPTIONS=--openssl-legacy-provider node ...andnode --openssl-legacy-provider ...→ md4 digests both succeed (866437cb...), both invocation forms verified;openssl version= 3.5.5;openssl list -digest-algorithmsshows MD4 only under legacy entries (RSA-MD4 => MD4) — corroborates "md4 not in the default provider".
Evidence details kept locally (2026-08-29)
Applicable tools (2)
This problem is linked from the tool pages below — reachable from either side.
nodenpmSource & evidence
← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk