Node.js ERR_OSSL_EVP_UNSUPPORTED - Fix "digital envelope routines"
Node 17+ bundles OpenSSL 3, which removed several legacy algorithms. Old webpack 4 / build tooling still asks for MD4 to hash module ids, and OpenSSL 3 refuses it.
What this error means
A build (often webpack 4, an old CRA, or a tool using the legacy hash) crashes immediately with ERR_OSSL_EVP_UNSUPPORTED and an error:0308010C:digital envelope routines::unsupported stack. The same project built fine on Node 16 and broke after a Node bump.
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash)
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'Diagnose it: what is different about the runner?
A build that passes locally and fails on a runner differs in a small number of predictable ways. Check those before changing build configuration, because the build config is usually not the thing that changed.
- run: |
node --version && npm --version
echo "NODE_ENV=$NODE_ENV CI=$CI"
nproc && free -h && df -h /
ls -la node_modules/.bin | headCommon causes
OpenSSL 3 dropped the legacy hash the tool uses
Webpack 4 (and some loaders) hash module identifiers with MD4 via Node’s crypto. OpenSSL 3, shipped in Node 17+, no longer enables that algorithm, so the call throws.
A Node version bump exposed an old toolchain
Nothing in your code changed - moving CI from Node 16 to 18/20 swapped OpenSSL 1.1 for OpenSSL 3, and the unmaintained build tool has not migrated.
How to fix it
Upgrade the build tool (preferred)
The real fix is to move to a webpack 5 / modern toolchain that no longer relies on the legacy hash.
# webpack 5 uses a supported hash by default
npm install webpack@latest webpack-cli@latest
npm run buildRe-enable the legacy provider as a stopgap
If you cannot upgrade yet, the OpenSSL legacy provider unblocks the build.
# one-off
NODE_OPTIONS=--openssl-legacy-provider npm run build
# in a workflow
env:
NODE_OPTIONS: --openssl-legacy-providerThe three that account for most of them
- Case sensitivity. Linux runners are case sensitive, macOS is not. An import with the wrong case resolves locally and fails in CI.
- Out of memory. Exit code 137 is a SIGKILL from the kernel, not a build error. Raise
--max-old-space-sizeor use a larger runner. - devDependencies pruned.
NODE_ENV=productionmakesnpm ciskip devDependencies, so the build tool itself goes missing. Set it after install, not before.
How to prevent it
- Keep bundlers on a maintained major before bumping Node.
- Test a Node upgrade in CI before rolling it everywhere.
- Drop --openssl-legacy-provider once the toolchain is modern.