macOSで「Too many open files」(EMFILE) エラーを修正する方法

intermediate🍎 macOS2026-04-19| macOS (Monterey, Ventura, Sonoma), Node.js, MongoDB, Webpack, VS Code

Error Message

Error: EMFILE: too many open files
#macos#ulimit#node#mongodb

エラーメッセージ

大規模なビルドの最中やローカルデータベースの起動時に、突然すべてが停止してしまうことがあります。ターミナルには大量のテキストが表示され、通常はこの行で締めくくられます:

Error: EMFILE: too many open files, open '/path/to/your/project/file.js'

時には、さらに不可解なエラーが発生し、手動での設定変更すら拒否されることもあります:

ulimit: open files: cannot modify limit: Invalid argument

根本原因:macOSのセーフティ機能

デフォルトの状態では、macOSのファイル記述子(file descriptors)の制限は驚くほど厳しく設定されています。多くの場合、1つのプロセスにつきわずか256個または1,024個のファイルに制限されています。10年前ならそれで十分でしたが、現代の開発環境ははるかに多くのリソースを消費します。

標準的なNext.jsやViteのプロジェクトを例に考えてみましょう。一度のnpm installだけで、node_modulesディレクトリ内に30,000以上のファイルが作成されることがあります。コンパイラがこれらのファイルを同時にインデックスしようとすると、すぐに1,024の上限に達してしまいます。その結果、オペレーティングシステムが介入してリクエストを強制終了し、システムリソースを保護するためにEMFILEエラーを発生させます。

解決策1:クイックフィックス(現在のターミナルのみ)

今すぐビルドを完了させる必要がある場合は、アクティブなターミナルタブの制限を一時的に引き上げることができます。この変更は一時的なもので、ウィンドウを閉じると無効になります。

まず、現在の制限を確認します:

ulimit -n

出力結果が256または1024であれば、低すぎます。このセッションの制限を65,536に引き上げるには、以下のコマンドを実行してください:

ulimit -n 65536

もう一度ビルドを実行してみてください。これで、クラッシュすることなく完了するのに十分な余裕ができるはずです。

解決策2:シェル設定を永続化する

ほとんどのmacOSユーザーはZshを使用しています。作業を開始するたびにulimitコマンドを実行しなくて済むよう、シェルの設定ファイルに追加しましょう。

  • 設定ファイルを開きます:
nano ~/.zshrc
  • 一番下に以下の行を貼り付けます:
# 開発用に最大オープンファイル数を増やす
ulimit -n 65536
  • Ctrl + OEnter、次にCtrl + Xの順に押して、保存して終了します。
  • 変更を強制的に反映させます:
source ~/.zshrc

解決策3:システム全体に適用する(推奨)

IDE(VS Codeなど)やバックグラウンドサービス(MongoDBなど)が原因の場合、シェルの調整だけでは解決しません。これらのアプリケーションは、必ずしも.zshrcの設定を継承するわけではないからです。これをカーネルレベルで修正するには、launchctlを使用する必要があります。

以下の手順に従って、永続的なシステム構成を作成します:

  • 新しいシステムレベルの設定ファイルを作成します:
sudo nano /Library/LaunchDaemons/limit.maxfiles.plist
  • 以下のXMLコードを挿入します。これにより、「ソフト」制限が64kに、「ハード」制限が512kに設定されます:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>limit.maxfiles</string>
  <key>ProgramArguments</key>
  <array>
    <string>launchctl</string>
    <string>limit</string>
    <string>maxfiles</string>
    <string>65536</string>
    <string>524288</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>
  • システムが受け入れるように、ファイルのパーミッションを設定します:
sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
sudo chmod 644 /Library/LaunchDaemons/limit.maxfiles.plist
  • 新しい設定を読み込みます:
sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
  • Macを再起動します。完全に再起動することで、これらのカーネルレベルの変更が開くすべてのアプリに適用されます。

結果の確認

再起動後、新しい制限が有効になっているか確認します。新しいターミナルを開き、以下を実行してください:

launchctl limit maxfiles

出力に65536524288が表示されるはずです。数値がまだ低い場合は、.plistファイルのXML構文を再確認してください。

予防策とベストプラクティス

  • ウォッチャーの管理: nodemonchokidarなどのツールは、変更を検知するためにファイルウォッチャーを使用します。5つの異なるプロジェクトを同時に実行したままにすると、すぐにクォータを使い果たしてしまいます。使用していないプロジェクトは閉じましょう。
  • node_modulesの監査: IDEが検索結果のためにnode_modulesフォルダ全体をインデックスしようとしていないか確認してください。最近の主要なエディタの多くはデフォルトでこれを除外していますが、設定を確認する価値はあります。
  • 接続のクリーンアップ: カスタムスクリプトを作成する場合は、必ずファイルストリームやデータベース接続を閉じてください。たとえ制限を65kにしても、記述子を無期限に開き続けるメモリリークが発生すれば防ぎようがありません。

Related Error Notes