Skip to content
DevOps2026-09-083 min read

error:0308010C digital envelope routines::unsupported — Fixing Node 17+ Breakage in Older Projects

Symptom: worked yesterday, npm run dev explodes today

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:130:10)
    at BulkCacheDecorator.cheaderHash (...)   ← inside webpack 4

One-line diagnosis: your Node version is 17+, and the webpack 4 inside the project still uses MD4 — a hash algorithm that OpenSSL 3.0 removed from its defaults. Your code isn't broken; your runtime and your build tool disagree.

Common triggers:

  • New machine or reinstall, and nvm defaulted to the latest LTS (Node 18/20/22)
  • CI base image upgrade (node:16node:20)
  • A Dockerfile that says FROM node:latest
  • Inheriting a legacy project (Vue CLI 4, create-react-app 4, raw webpack 4)

Root cause: OpenSSL 3.0 vs MD4

Starting with Node 17, Node bundles OpenSSL 3.0. OpenSSL 3.0 moved legacy algorithms like MD4 into the "legacy provider," which is not loaded by default. webpack 4 computes module hashes with crypto.createHash('md4') — so the very first call throws.

Decode the hex in the error: 0308010C is ERR_OSSL_EVP_UNSUPPORTED. And it's not only webpack 4 — old versions of grunt, gulp-rev, and some crypto-js releases hit the same wall.

Fix 1: enable the legacy provider (5-minute unblock)

Pass --openssl-legacy-provider so Node loads MD4 again:

# macOS / Linux
export NODE_OPTIONS=--openssl-legacy-provider
npm run dev

# Windows CMD
set NODE_OPTIONS=--openssl-legacy-provider

# Windows PowerShell
$env:NODE_OPTIONS="--openssl-legacy-provider"

The durable version lives in package.json and works cross-platform (requires the cross-env devDependency):

{
  "scripts": {
    "dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve",
    "build": "cross-env NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build"
  }
}

When to use it: the project has a few months of life left, or you're just passing through. The tradeoff: MD4 is considered insecure, so you're extending technical debt — fine for now, but the upgrade question comes back eventually.

Fix 2: upgrade to webpack 5 (the real fix)

| Project type | Upgrade path | |---|---| | Vue CLI 4 | vue upgrade to Vue CLI 5 (webpack 5 built in) | | CRA 4 | migrate to CRA 5, or jump straight to Vite | | Hand-rolled webpack 4 | npm i webpack@5 webpack-cli@4 -D, then work through breaking changes |

webpack 5 switched its default hashing to xxhash64/sha256, fully compatible with OpenSSL 3. You also get persistent caching and faster production builds as a bonus.

Post-upgrade gotcha: PolyfillPlugin errors about missing assert/process — webpack 5 no longer auto-polyfills Node core modules. Add them one by one via resolve.fallback or install the npm shims as errors surface.

Fix 3: pin Node 16 (stopgap)

nvm install 16
nvm use 16
node -v   # v16.x

Add a .nvmrc at the repo root:

16

Mirror it in CI and your Dockerfile:

FROM node:16-alpine

Warning: Node 16 reached end-of-life in September 2023 and receives no security patches. Use it only as a bridge while the webpack 5 upgrade is scheduled — never as a destination.

Choosing between the three

| Fix | Cost | Risk | Best for | |---|---|---|---| | --openssl-legacy-provider | 5 min | Low (process-scoped) | Fast unblock, legacy maintenance mode | | Upgrade webpack 5 | 0.5–3 days | Medium (build behavior drift) | Projects with a future | | Pin Node 16 | 10 min | High (no security patches) | CI parity, temporary holdover |

Prevention: nail the Node version to the project

The underlying problem is runtime drift. Three lines of defense:

  1. .nvmrc plus the engines field in package.json:
{
  "engines": { "node": ">=18 <19" }
}
  1. Enforce it in CI (add engine-strict=true to .npmrc) so a wrong Node version fails loudly instead of producing cryptic errors;
  2. Never use node:latest in a Dockerfile — pin the major version.

Checklist

  1. node -v — is it ≥17? Is webpack 4.x (npm ls webpack)?
  2. Error contains 0308010C / digital envelope routines — confirmed diagnosis
  3. Emergency: NODE_OPTIONS=--openssl-legacy-provider to get running
  4. Schedule the webpack 5 upgrade, or .nvmrc pin to 16 as a stopgap
  5. Re-check .nvmrc, engines, and Dockerfile agree on the same Node version

Provided by ToolVault. Related: ERESOLVE conflicts, npm registry mirror guide, Cannot find module. See the homepage for more developer tools.


Advertisement