error:0308010C:digital envelope routines::unsupported
A step-by-step skill for fixing Node's 'error:0308010C:digital envelope routines::unsupported' build failure: the OpenSSL 3 vs webpack 4 md4 clash. Covers the NODE_OPTIONS legacy-provider unblock and the real fix of upgrading the toolchain. Use when builds break after moving to Node 17+. Triggers: 'digital envelope routines', 'error:0308010C', 'md4', 'createHash'. Not for: runtime TLS errors, expired certificates, or non-Node build failures.
error:0308010C:digital envelope routines::unsupported
TL;DR
Node 17 and newer ship OpenSSL 3, which removed the old md4 hash that webpack 4 uses for build hashing. Quick unblock: set NODE_OPTIONS=--openssl-legacy-provider. Real fix: upgrade the build toolchain to versions that use a modern hash.
error:0308010C:digital envelope routines::unsupportedUse this when
- A Node build that worked on Node 16 fails on Node 17 or newer with this error
- The stack trace mentions createHash or md4, usually inside webpack
- CI fails after a Node version bump with no code changes
- A Docker build breaks when the base image moves to a newer Node
Not for this skill when
- The error happens at runtime during TLS connections (different problem)
- You're on Node 16 or older (this error is coming from somewhere else)
- The failing tool isn't Node-based at all
Steps
- Confirm the Node and OpenSSL versions:
node -v && node -p "process.versions.openssl"Expected: Node 17 or newer with OpenSSL 3.x. If you're on Node 16 or older, stop; this isn't the md4 issue.
- Confirm the old hasher is the trigger:
npm run build |& grep -i -m2 "md4"Expected: a line pointing at crypto.createHash with md4 or webpack's hashing code.
- Unblock the build right now:
export NODE_OPTIONS=--openssl-legacy-provider
npm run buildExpected: the build succeeds. Treat this as a bandage, not the fix; the legacy provider re-enables weak hashes for the whole process.
- Do the real fix: upgrade webpack to v5 (or the framework version that bundles it) so hashing uses a supported algorithm. If you're stuck on webpack 4, set the hash function explicitly:
// webpack.config.js
module.exports = { output: { hashFunction: "sha256" } };Expected: builds pass with no NODE_OPTIONS override.
- Remove the bandage from CI configs and Dockerfiles once upgraded, and grep the repo so it doesn't linger:
grep -r "openssl-legacy-provider" --include="*.yml" --include="Dockerfile" --include="*.json" .Expected: no hits remain.
Variant: same error from Angular CLI or react-scripts 4
Same webpack-4 root cause underneath. Upgrade the framework toolchain; the legacy-provider flag is the same temporary unblock.
Variant: error inside a Docker build
Pin a Node 16 base image as the bandage, or upgrade the toolchain in the image. Remember the flag has to be set in every RUN step that builds, not just the final image env.
Variant: error:03000086 sibling
Also an OpenSSL 3 initialization failure. Same playbook: confirm versions, bandage with the legacy provider, fix by upgrading.
Why this happens
OpenSSL 3 moved md4 and other legacy algorithms behind a legacy provider that Node doesn't load by default. Webpack 4 hardcodes md4 for module hashing, so any Node 17 or newer build of a webpack-4 project fails at hash time. Nothing about your code changed; the crypto library underneath it did.
Edge cases and pitfalls
- The legacy flag must be set for every process in the build: CI steps, Docker RUN lines, and any child scripts.
- Some platforms ignore NODE_OPTIONS inside npm scripts; export it in the shell profile or the CI env block instead.
- Upgrading major framework versions can be a real project; budget it, because the flag is a workaround with a weaker crypto posture.
- If the build still fails with the flag set, something else is also using a removed algorithm; read the full stack, not just the first line.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_Izog0sMBmc6IWwXfYTYKKQ