Skip to content
Latchkey

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.

Build output
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.

.github/workflows/ci.yml
- run: |
    node --version && npm --version
    echo "NODE_ENV=$NODE_ENV  CI=$CI"
    nproc && free -h && df -h /
    ls -la node_modules/.bin | head

Common 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.

Terminal
# webpack 5 uses a supported hash by default
npm install webpack@latest webpack-cli@latest
npm run build

Re-enable the legacy provider as a stopgap

If you cannot upgrade yet, the OpenSSL legacy provider unblocks the build.

Terminal / workflow
# one-off
NODE_OPTIONS=--openssl-legacy-provider npm run build

# in a workflow
env:
  NODE_OPTIONS: --openssl-legacy-provider

The 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-size or use a larger runner.
  • devDependencies pruned. NODE_ENV=production makes npm ci skip 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.

Frequently asked questions

Is this a security problem in my app?
No - it is OpenSSL 3 refusing a deprecated algorithm a build tool asked for. The risk is in re-enabling the legacy provider broadly; the clean fix is upgrading the tool so the legacy algorithm is never requested.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card