Errors and fixes
error:0308010C digital envelope routines::unsupported: cause and fix
The error appears when Node 17 or later runs a toolchain that asks OpenSSL 3 for md4. Here is why it happens, the temporary fix and the lasting one.
Key points
- This is not a bug in your code: the bundler asks OpenSSL 3 for an algorithm that moved to the legacy provider.
- `NODE_OPTIONS=--openssl-legacy-provider` unblocks the build but re-enables weak algorithms across the whole Node process.
- The lasting fix is updating the bundler (webpack 5, Vite, rspack), not going back to Node 16.
Short answer: the bundler asked OpenSSL 3 for an algorithm, md4, that OpenSSL 3 no longer exposes in the default provider. This is not a bug in your code and you cannot fix it in the code: you fix it by updating the tool that computes the hashes, or by telling Node to re-enable the legacy provider.
The exact message
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:79:19)
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
The 0308010C prefix is the OpenSSL code: it says the requested algorithm is not available under the current provider settings. The rest of the stack shows where Node tried to create the hash.
Why it happens
Node 17 moved to OpenSSL 3. Webpack 4, and the tools that wrap it such as create-react-app 4, vue-cli 4 and some Next 11 setups, uses md4 to compute chunk identifiers. OpenSSL 3 keeps md4 in the legacy provider, off by default because it counts as weak.
Hence the paradox: the project is not ten years old, yet one build step depends on an algorithm the operating system no longer considers safe.
Quick fix, as a stopgap
# macOS / Linux
NODE_OPTIONS=--openssl-legacy-provider npm run build
# PowerShell
$env:NODE_OPTIONS = "--openssl-legacy-provider"
npm run build
The flag re-enables the legacy provider for the whole Node process. It works at once and is fine for unblocking a local build. Do not leave it in the production pipeline: it re-enables weak algorithms for code that never asked for them.
The lasting fix
- Update the bundler to webpack 5, or move to Vite or rspack.
- On create-react-app, take react-scripts to 5 or migrate to Vite: version 4 will get no further fixes.
- If a dependency pins the bundler, isolate that dependency: the problem is its own, not the whole project's.
npm ls webpack
npx webpack --version
The first command shows who pulls webpack into the dependency tree; the second shows the version actually in use. A version 4 answer means the legacy flag is a symptom, not the cure.
When the fix does not work
If the error survives with NODE_OPTIONS set, the failing process never inherited the environment. That happens with scripts that spawn a second Node, with containers that drop variables, or with a command that runs a separate worker. Check with node -p process.env.NODE_OPTIONS inside the script that fails: an empty line means the variable did not arrive.
How to prevent it
- Pin the Node major in
.nvmrcand inenginesin package.json. - Build in CI with the same major you use locally: the gap between the two is the most common cause.
- Treat every use of
--openssl-legacy-provideras technical debt with an expiry date.
Where to continue
The EneUI catalogue holds 111,985 components and 1,556 blocks with previews: the records are already compiled, so they never force you to patch a legacy toolchain. To see which library costs least at build time read how much a UI library weighs; for project structure, App Router in 2026; for the comparison of alternatives to MUI. The ranking of measured catalogues is at /best/ui-catalogues.
Frequently asked questions
Is --openssl-legacy-provider safe in production?
No. It re-enables algorithms that OpenSSL 3 treats as legacy for the whole Node process, not just the command that needs them. Use it to unblock a local build and remove it before CI.
Why does the build pass on my machine and fail in CI?
Almost always because the two machines run different Node majors, and OpenSSL 3 arrived with Node 17. Compare node -v in both environments before touching the code.
Should I go back to Node 16?
No. Node 16 is out of support. The right move is to update the toolchain that calls md4.
Does the error affect Vite too?
Usually not: Vite uses esbuild and Rollup, which do not depend on md4. If you see it with Vite, a plugin or a separate script is invoking webpack.
How do I find the package that causes it?
Start from npm ls webpack and see which tool pulls it in. When the build goes through create-react-app, react-scripts 4 is the culprit.