Node.js v17以降での ERR_OSSL_EVP_UNSUPPORTED
エラーとその対処法
はじめに
Node.js v17系以降で、npm run dev
等のコマンドを実行した際に以下のようなエラーに遭遇したことはありませんか?
Error: error:0308010C:digital envelope routines::unsupported
これは ERR_OSSL_EVP_UNSUPPORTED
というエラーで、内部のOpenSSLライブラリの変更によって引き起こされる問題です。
本記事では、この原因と対処法について解説します。
原因
Node.js v17以降では、内部で使用されるOpenSSLのバージョンが 1系から3系に変更されました。
その結果、OpenSSL 3系では一部の**非推奨の暗号アルゴリズム(例:md4)が無効化され、Node.jsでそれらを使おうとすると ERR_OSSL_EVP_UNSUPPORTED
エラーが発生します。
筆者の環境ではwebpackを使ったプロジェクトのビルド時にこのエラーが発生しました。原因を調べたところ、webpack v4が内部で使用しているmd4というハッシュアルゴリズムが、OpenSSL 3系では非推奨となったことが影響していました。
解決方法
以下のように、Node.jsの実行時に環境変数 NODE_OPTIONS
に --openssl-legacy-provider
を指定することで回避できます。
macOS / Linuxの場合
NODE_OPTIONS=--openssl-legacy-provider npm run dev
Windows(cmd)の場合
set NODE_OPTIONS=--openssl-legacy-provider && npm run dev
package.jsonに記述する例
"scripts": {
"dev": "NODE_OPTIONS=--openssl-legacy-provider"
}
このオプションの意味と注意点
--openssl-legacy-provider
は、Node.jsに搭載されている標準ライブラリのOpenSSL3系で非推奨となったレガシーの暗号アルゴリズムを一時的に有効にするためのオプションです。
よく誤解されていると思われるのが、このオプションはOpenSSL1系の動作を再現するわけではなく、実際にはエラーの原因となっている非推奨のレガシーな暗号アルゴリズムの使用が許可されるだけです。TLS/SSLプロトコルなど他の機能や関数はすべてOpenSSL3系で動作します。
なぜこの問題はwebpack v4で発生するのか?
今回、筆者の環境で発生したエラーは、使用していたモジュールバンドラー webpack v4 が原因でした。
webpack v4では、バンドル後のファイル名の生成にOpenSSLのハッシュ関数(md4)を使用しています。しかし、このmd4は、OpenSSL 3系で非推奨になったため、Node.js v17以降の環境ではエラーが発生します。
なお、webpack v4はmd4を暗号処理などのセキュリティ目的では使ってないため(のはず)、一時的に --openssl-legacy-provider
を使って回避しても、実害はないといえるでしょう。とはいえ、今後の互換性を考慮して、webpack 5以降への移行を検討するのが望ましいです。Webpack 5.61.0ではこの問題が解決済みです。
まとめ
- Node.js v17以降はOpenSSL 3系が採用され、非推奨の暗号化関数(md4など)が無効化される
-
NODE_OPTIONS=--openssl-legacy-provider
を指定すれば回避可能