VVersions.dev

Fix Node.js dependency errors

Node dependency errors after an upgrade usually trace to a few causes: native modules built against the old ABI, a dependency whose engines range excludes the new Node, OpenSSL 3 stricter defaults, or CommonJS/ESM interop. Reproduce on a clean install before changing code.

WorkflowDifficulty: moderatemedium risk

Last verified · Updated May 22, 2026

A Node dependency error after an upgrade almost always traces to one of four causes: a native module compiled against the old ABI, a dependency whose engines range excludes the new Node, OpenSSL 3 stricter crypto/TLS defaults, or a CommonJS/ESM interop mismatch. Reproduce on a clean install with the pinned Node version before touching code.

Symptoms

  • 'Error: Module did not self-register' or a NODE_MODULE_VERSION mismatch at startup.
  • npm warns 'engine "node" is incompatible with this module'.
  • ERR_REQUIRE_ESM or 'require() of ES Module' when loading a dependency.
  • TLS/crypto errors (e.g. unsupported legacy algorithms) that only appear after the upgrade.

Likely causes

  • Native addon (.node binary) built against the previous Node ABI.
  • A dependency declaring an engines.node range that excludes the new version.
  • A dependency shipping ESM-only that your CommonJS code require()s.
  • OpenSSL 3 disabling a legacy algorithm the dependency relied on.
  • A stale node_modules or lockfile resolved under the old Node.

Diagnostic commands

shell
# Reproduce on a clean install with the pinned Node version$ node --version$ rm -rf node_modules && npm ci# Rebuild native modules against the current ABI$ npm rebuild# Find dependencies whose engines range excludes this Node$ npm ls --all 2>&1 | grep -i "engine" || true

Common error patterns

SymptomLikely causeTypical fix
NODE_MODULE_VERSION mismatchNative addon built against old ABIReinstall and run npm rebuild
Module did not self-registerStale prebuilt .node binaryrm -rf node_modules && npm ci, then npm rebuild
engine "node" is incompatibleDependency engines range excludes new NodeUpgrade the dependency or find a compatible replacement
ERR_REQUIRE_ESMrequire() of an ESM-only packageUse dynamic import() or move the caller to ESM
unsupported / legacy crypto errorOpenSSL 3 stricter defaultsUpdate the dependency; avoid --openssl-legacy-provider as a permanent fix
Rebuild native modules before assuming a code bug

After a Node major upgrade the V8/N-API ABI changes, so any package with native bindings must be reinstalled or rebuilt. Most 'Module did not self-register' and NODE_MODULE_VERSION errors are stale addons, not application bugs — run npm rebuild first.

Test failure debuggingAI debugging prompt
My Node.js app fails to start after upgrading Node. Here is the error, the output of `node --version`, and `npm ls` for the failing package: <paste>. Identify the root cause — native ABI mismatch, an engines incompatibility, ESM/CommonJS interop, or an OpenSSL 3 change — and propose the smallest correct fix. Prefer rebuilding native modules or upgrading the offending dependency over global workarounds like --openssl-legacy-provider.

Safety: Do not recommend --openssl-legacy-provider or pinning Node back to EOL as a permanent fix. Each fix must address the underlying cause.

Safe fix workflow

  1. Confirm the running Node version matches the pinned version (.nvmrc / engines.node).
  2. Reinstall from a clean state: rm -rf node_modules && npm ci.
  3. Run npm rebuild to rebuild native addons against the current ABI.
  4. For an engines incompatibility, upgrade the dependency or find a maintained replacement.
  5. For ERR_REQUIRE_ESM, switch the caller to dynamic import() or move it to ESM.
  6. For OpenSSL 3 errors, update the dependency rather than enabling the legacy provider.

Escalation checklist

  • A native dependency has no Node 20-compatible prebuilt binary and won't build from source
  • A critical dependency declares an engines range with no compatible release
  • An OpenSSL 3 error has no fix short of the legacy provider
  • The error reproduces only in CI or only in the Docker image, not locally

Official sources

  • GitHub releaseNode.js releasesnodejs/nodereliability 92%

    Backs the breaking-change and migration-step claims.

  • ChangelogNode.js ECMAScript Modulesnodejs.orgreliability 98%

    Backs the breaking-change and migration-step claims.