Node.js エラー ERR_OSSL_EVP_UNSUPPORTED の解決方法
問題の概要
Node.js 18 以降で React アプリケーションをビルドまたは実行する際に、以下のエラーが発生することがあります:
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:71:19)
at Object.createHash (node:crypto:133:10)
at module.exports (/app/node_modules/webpack/lib/util/createHash.js:135:53)
...
このエラーは、Docker コンテナ内でアプリケーションを実行する際や、開発サーバーを起動する際に頻繁に発生します。
エラーの原因
技術的背景
Node.js v17.0.0 で OpenSSL 3.0 が採用され、従来の暗号化アルゴリズムの一部が非推奨となりました。具体的には、MD4 アルゴリズムがデフォルトで無効化されており、これが Webpack などのビルドツールでハッシュ生成に使用されていたため、互換性の問題が発生しています。
主な原因:
- Node.js バージョン 17 以上を使用している
- プロジェクトの依存関係(特に Webpack)が古い暗号化アルゴリズムに依存している
- OpenSSL 3.0 のセキュリティ向上による後方互換性の問題
解決方法
方法 1: Node.js のバージョンダウン (推奨)
最も安全な解決策は、Node.js 16 LTS バージョンにダウングレードすることです。
Dockerfile の場合:
FROM node:16-alpine # 18ではなく16を使用
EXPOSE 3000
WORKDIR /app
COPY ./frontend/package.json .
RUN npm install
COPY ./frontend .
COPY ./images .
CMD ["npm", "start"]
ローカル環境の場合、nvm (Node Version Manager) を使用:
# 利用可能なNode.jsバージョンを確認
nvm ls
# Node.js 16をインストール(まだない場合)
nvm install 16
# Node.js 16を使用
nvm use 16
方法 2: 環境変数での暫定対策
一時的な解決策として、OpenSSL のレガシープロバイダを有効にします。
注意
この方法はセキュリティ上のリスクがあるため、本番環境では推奨されません。あくまで暫定的な解決策として使用してください。
Dockerfile で設定する場合:
FROM node:18-alpine
ENV NODE_OPTIONS="--openssl-legacy-provider"
EXPOSE 3000
WORKDIR /app
# ... その他の設定
package.json のスクリプトを変更する場合:
{
"scripts": {
"start": "react-scripts --openssl-legacy-provider start",
"build": "react-scripts --openssl-legacy-provider build",
"dev": "node --openssl-legacy-provider ./node_modules/.bin/next dev"
}
}
方法 3: プロジェクトの依存関係を更新
根本的な解決のためには、プロジェクトの依存関係を更新して最新の暗号化標準に対応させます:
# npm の場合
npm update
# yarn の場合
yarn update
プラットフォーム別の設定
Windows 環境
set NODE_OPTIONS=--openssl-legacy-provider
npm start
Linux/macOS 環境
export NODE_OPTIONS=--openssl-legacy-provider
npm start
PowerShell 環境
$env:NODE_OPTIONS = "--openssl-legacy-provider"
npm start
フレームワーク別の対応
React / Create React App
{
"scripts": {
"start": "react-scripts --openssl-legacy-provider start",
"build": "react-scripts --openssl-legacy-provider build"
}
}
Next.js
{
"scripts": {
"dev": "node --openssl-legacy-provider ./node_modules/.bin/next dev",
"start": "node --openssl-legacy-provider ./node_modules/.bin/next start",
"build": "node --openssl-legacy-provider ./node_modules/.bin/next build"
}
}
まとめ
このエラーは Node.js のバージョンアップに伴う OpenSSL の変更が原因です。以下のいずれかの方法で解決できます:
- 推奨: Node.js 16 LTS にダウングレード
- 暫定策:
--openssl-legacy-provider
フラグを使用 - 根本的解決: プロジェクトの依存関係を更新
ベストプラクティス
本番環境では、セキュリティを考慮して Node.js 16 LTS の使用または依存関係の更新を推奨します。--openssl-legacy-provider
は開発時のみの暫定策として利用してください。
プロジェクトの状況に応じて適切な解決方法を選択し、安全な開発環境を構築しましょう。