
Too many open files の対処|ファイルディスクリプタ枯渇の見つけ方
アプリが急にエラーを吐き始めた。ログを見ると Too many open files。あわてて df -h や free を打っても——ディスクもメモリも、まだ余裕がある。
この「リソースは空いているのに、ファイルもソケットも開けない」状況は、保守運用でわりと焦りやすい障害ですよね。容量でもメモリでもないなら、いったい何が足りないのか。原因のわからないまま、アプリだけが「開けない」と言い続けて、時間が過ぎていきます。
でも、落ち着いて大丈夫です。この症状の多くは、ファイルディスクリプタ(file descriptor=開けるファイルの「数」の上限)の枯渇という、はっきり原因のある状態です。容量やメモリではなく、「同時に開けるファイルの数」の上限に当たっているだけ。見る場所さえ分かれば、順番にたどって落ち着けます。
この記事では、どのプロセスが・いくつ開いているかの見つけ方から、上限(ulimit)の確認、その場をしのぐ一次対処、そしてリークを止める再発防止までを一緒に整理します。ディストリビューションや起動方法(systemd/シェル)で細部は変わりますが、「開ける数の上限を疑って、どこが使い切っているかを探す」という流れはそのまま使えます。
結論:まず、エラーを出しているのが どのプロセスかを特定し、そのプロセスが いま何個のファイルを開いているか(ls /proc/<PID>/fd | wc -lやlsof -p <PID> | wc -l)と、そのプロセスに許された上限(cat /proc/<PID>/limitsのMax open files)を突き合わせます。数が上限に張り付いていれば、原因は容量でもメモリでもなく ファイルディスクリプタ(FD)の枯渇です。急ぎなら該当プロセスの安全な再起動でいったん解放し、そのうえで 開きっぱなし(リーク)や上限の低さという根っこを手当てします。ソケットの開きすぎも同じFDを食うので、「ファイルだけ」と思い込まないのがコツ。あわてて上限を最大まで上げる前に、まず「数だった」「どこが握っているか」を1つに絞るのが、結果的にいちばん早いです。
何が起きているか:FDは「開いている間だけ借りる番号札」
まず、正体をはっきりさせます。Linuxでは、プロセスがファイルを開くと ファイルディスクリプタ(FD) という小さな整数の「番号札」が1枚割り当てられます。ここで大事なのは、FDを使うのはファイルだけではないことです。
- ファイルも、ソケット(ネットワーク接続)も、パイプも、みんなFDを1枚ずつ消費します。だから「ファイルは開いていないのに Too many open files」も、ふつうに起こります。DB接続やHTTP接続を大量に張れば、それだけでFDは減っていきます。
- FDには上限(ulimit の open files)があります。プロセス1つが同時に開けるFDの数に上限があり、そこに当たると、新しくファイルやソケットを開こうとした瞬間に
Too many open files(EMFILE) というエラーが返ります。 - 閉じ忘れ(リーク)で、じわじわ減ることもあります。開いたFDをちゃんと閉じないコードやライブラリだと、処理を繰り返すたびにFDが積み上がり、動き始めてしばらくして上限に当たる——という時間差の障害になりがちです。
つまり、df(容量)や free(メモリ)だけを見て「空いてるのに変だ」と悩むのは、別のメーターを見ている状態なんです。見るべきは「開いているファイル・ソケットの数」というメーター。ここを開ければ、たいていは霧が晴れます。
どこから見るか:容量でもメモリでもなく「開いている数」を開く

順番はシンプルです。①どのプロセスかを特定する → ②その数と上限を突き合わせる → ③その場をしのぐ(一次対処)→ ④リークと上限を手当てする(再発防止)。手前から一段ずつ進みます。
① まず「誰が Too many open files を出しているか」を特定する
最初に、エラーを出しているプロセスを1つに絞ります。ここが決まらないと、あとの確認先が定まりません。
- アプリのログとプロセスを対応づける:
Too many open filesがどのサービスのログに出ているかを見て、対応するプロセス(PID)をpsなどで確認します。Webなら nginx/php-fpm/アプリのワーカー、常駐バッチなら該当のデーモン、というようにまず1プロセスに当たりをつけるのが先です。 - システム全体か、1プロセスかを見分ける:多くの場合は「特定プロセスがそのプロセスの上限に当たっている」ケースです。まれにシステム全体のFD上限(
/proc/sys/fs/file-nrの使用数とfs.file-max)に近づいていることもあるので、頭の隅に置いておきます。まずは個別プロセス、が実務の入口です。
犯人のPIDが分かれば、次は「そのプロセスが今いくつ開いていて、上限はいくつか」を突き合わせるだけです。
② 「開いている数」と「上限」を突き合わせる
ここが今回の核心です。現在の使用数と許された上限を並べて見ます。
- 今いくつ開いているかを数える:
ls /proc/<PID>/fd | wc -lで、そのプロセスが現在開いているFDの数が分かります(/proc/<PID>/fdは開いているFDが並ぶディレクトリです)。lsof -p <PID> | wc -lでも近い数が見られます。 - そのプロセスの上限を見る:
cat /proc/<PID>/limitsを見て、Max open files(Soft/Hard) の値を確認します。シェルから起動したものならulimit -n(ソフト上限)でも見られますが、サービスは起動時の上限を引き継ぐので、いま動いているプロセスの実際の上限は/proc/<PID>/limitsを見るのが確実です。 - 数が上限に張り付いていれば確定:使用数が
Max open filesに達している(またはすぐ手前)なら、原因はFDの枯渇です。正体が分かった時点で、対処の半分は終わっています。 - 何を大量に握っているかを覗く:
lsof -p <PID>の中身を見ると、同じファイルを何百も開いているのか、ソケット(TCP/can't identifyなど)が大量なのかが見えます。ここが後の「リークかどうか」の見極めにつながります。
もし数が上限にまったく届いていないのにエラーが出るなら、別プロセスの取り違え、あるいはシステム全体の上限側を疑う番です。「数が上限に当たっているか」で切り分けるのが、迷わないコツです。
ひと呼吸おきましょう。dfやfreeを見て「空いてるのに開けない」と悩んでいた時間は、決して無駄ではありません。もう1つ「開いている数」というメーターがあると知っていれば、次からは最初の数分で正体にたどり着けます。
③ その場をしのぐ:安全に解放して、まずサービスを戻す
原因がFD枯渇だと分かったら、止まっている業務をまず戻します。ここは一次対処(急場をしのぐ)と割り切ります。
- 該当プロセスの安全な再起動:多くの場合、開きっぱなしのFDはプロセスを再起動すれば解放されます。まずは影響範囲を確認して、サービスを安全に再起動し、業務を戻します。これで「開けない」状態自体はいったん解けます。
- ただし再起動は「時間稼ぎ」と意識する:リークが原因なら、再起動してもまた同じ時間で戻ってきます。いつからおかしくなったか・どのくらいで上限に達したかを控えておくと、次の恒久対応がぐっと楽になります。
- 急ぎで上限を上げるなら慎重に:どうしても再起動できず、上限を一時的に引き上げてしのぐ場合もあります。ただし根っこがリークなら、上限を上げても到達を遅らせるだけです。上げるにしても「なぜ上げたか・元の値」を必ず記録し、恒久対応(④)とセットにします。
戻せたら、そこで終えないのが大事です。なぜ枯渇したのかを④で手当てして、同じ夜を繰り返さないようにします。
④ 根っこを手当てする:リークを止める・上限を適正化する
FD枯渇には、大きく「閉じ忘れ(リーク)」と「上限がそもそも低い」の2つの背景があります。どちらか(または両方)を切り分けて手当てします。
- リークを疑うサイン:稼働時間とともに
/proc/<PID>/fdの数が単調に増え続けるなら、閉じ忘れの可能性が高いです。lsof -p <PID>で、同じファイルやソケットが延々と積み上がっていないかを見ます。処理のたびにDB接続やファイルを開いて閉じていない、コネクションプールの設定が効いていない、といった実装・設定が疑わしいところです。 - リークの手当て:該当箇所を特定できたら、開いたら必ず閉じる(接続を使い回す・プールを効かせる・例外時もクローズする)方向で直します。すぐ直せない場合は、いったん定期再起動でしのぎつつ、恒久修正の時間を確保する——という段階対応も現実的です。暫定と恒久を分けて管理すると混乱しません。
- 上限が低すぎるなら適正化:接続数の多い正当な用途(多数の同時接続を捌くサーバー等)で、上限自体が実態に合っていないこともあります。その場合は上限を上げますが、根拠のある値にします。systemd 管理のサービスなら
LimitNOFILE、シェル起動系ならlimits.conf/ulimitが効きどころです(起動方法で効く設定が違うため、いま動いているプロセスの/proc/<PID>/limitsで反映を必ず確認します)。 - 監視に「開いている数」を足す:容量・メモリだけでなく、主要プロセスのFD使用数や、システム全体の
file-nrを監視・記録しておくと、上限に達する前に気づけます。平常値を知っておくと、「じわじわ増えている」異常に早く気づけます。
具体例:「昼過ぎに毎回アプリが Too many open files で落ちる」を追う
よくある一例を、順番に切り分けてみます。
- ①症状:アプリのワーカーが、毎日昼過ぎになると
Too many open filesを出して処理に失敗し始める。dfもfreeも余裕あり。再起動すると直るが、また翌日の同じころに再発。 - ②数と上限:エラー中のワーカーのPIDで
ls /proc/<PID>/fd | wc -lを打つと、cat /proc/<PID>/limitsのMax open filesにぴったり張り付いていた。容量でもメモリでもなく、FDの枯渇と確定。 - ③中身を覗く:
lsof -p <PID>を見ると、外部APIへのソケットが大量に積み上がっていた。処理のたびに接続を張るのに、閉じずに次へ進んでいた(=リーク)。ファイルではなくソケットが犯人だった。 - ④手当て:まず安全に再起動して業務を戻し(一次対処)、原因のコードで接続を使い回す/必ず閉じるように修正(恒久対応)。あわせて、そのワーカーのFD使用数を監視に追加した。「再起動で直る」で終わらせず、増え続ける中身を1回覗いたことが、本丸(閉じ忘れ)への近道になった。
もし「再起動すれば直るから」と毎日直し続けていたら、原因にはたどり着けなかったはずです。/proc/<PID>/fd の数と lsof の中身を一度見たからこそ、短い時間で根っこまで進めました。
影響:この障害を「知っている」だけで、対応が変わる
FD枯渇は、知らないと迷い、知っていれば数分で正体が分かる——差の出やすい障害です。
- 「容量もメモリも空いているのに開けない」で消耗する時間を、
/proc/<PID>/fdと/proc/<PID>/limitsの突き合わせでほぼ無くせる。 - 「ファイルだけ」と思い込まずソケットも数えると、外部連携やDB接続まわりの原因に早く気づける。
- 再起動で直る=解決、で止めない習慣がつき、リークを見逃さなくなる。
- 監視にFD使用数を足せば、上限に達する前に気づけるようになり、障害そのものが減る。
逆に、この存在を知らないままだと、同じ「開けない」で毎回ふりだしに戻り、再起動で延命し続けることになります。今日この記事で正体を1つ知ったことが、次の当直の自分を助けます。
明日やること:自分の現場のFDを、平常時に見ておく
障害の最中ではなく、落ち着いている今のうちにできる、いちばん小さな一歩です。
- 主要なサービスのプロセスで
cat /proc/<PID>/limitsを見て、Max open filesの上限を控える。まず「うちの上限はいくつか」を知るだけでいい。 - その同じプロセスで
ls /proc/<PID>/fd | wc -lを打ち、平常時のFD使用数を控える。上限に対してどのくらい余裕があるかを把握する。 - しばらく時間を空けてもう一度数え、増え続けていないかを軽く確認する。単調増加が見えたら、リークの芽かもしれない。
- 監視に、主要プロセスのFD使用数(または
/proc/sys/fs/file-nr)が入っているか確認する。容量・メモリだけなら、FDも足す。 - 分かったこと(上限・平常値・増え方)を、運用メモに1行残す。
全部を今日やらなくて大丈夫です。/proc/<PID>/fd の数と上限を一度突き合わせて、自分の現場の平常値を知る——それだけで、次に「Too many open files」に出くわしたとき、迷わず正体にたどり着けます。
Too many open files 切り分けチェックリスト
対応に着手するとき、これだけ確認できているかを見る項目です。コピーして自分のメモに当ててみてください。全部を毎回そろえる必要はありません。
まず外せない最低ラインはこの3つです。急いでいても、ここだけは押さえます。
- 【最低ライン】容量・メモリではなく、開いているFDの数を疑ったか
- 【最低ライン】該当プロセスの
Max open files(/proc/<PID>/limits)と、現在数(/proc/<PID>/fd)を突き合わせたか - 【最低ライン】一次対処(安全な再起動)で業務を戻したうえで、根っこを別途手当てする前提に立てたか
次の項目は、原因を奥まで追うとき・再発を止めたいときに追加で確認します。当てはまらなければ飛ばして大丈夫です。
-
lsof -p <PID>の中身を見て、ファイルかソケットか、何を大量に握っているか確かめたか - 稼働時間とともにFD数が単調増加していないか(リークの疑い)を確認したか
- 上限を上げる場合、起動方法に合った設定(systemdの
LimitNOFILE/limits.conf等)で行い、/proc/<PID>/limitsで反映を確認したか - システム全体の上限(
/proc/sys/fs/file-nrとfs.file-max)に近づいていないか見たか - 監視に主要プロセスのFD使用数を追加したか
- 暫定対応(再起動での延命)と恒久対応(リーク修正)を分けて記録したか
- 平常値と、効いた対処を運用メモに残したか
全部に○が付かなくても大丈夫です。最低ラインの「数と上限を突き合わせたか」さえ押さえられれば、容量・メモリ探しで消耗するより、ずっと確かな一歩になります。
よければ、こちらも
FD枯渇は、「開いた数を見張る監視」と「増え続ける原因を止める習慣」があるほど、起きにくくなります。ほかのリソース枯渇や、プロセスの調べ方とセットにしておくと、この手の障害がだいぶ軽くなります。
- ディスクは空きなのに書き込めない|inode枯渇の見つけ方と対処:「容量は空いているのに書けない」を「数」で切り分ける、まさに同じ考え方の障害です。あわせて持っておくと強いです。
- メモリ不足でプロセスが落ちる|OOMの兆候の見つけ方と一次対処:「リソースが足りずにプロセスが落ちる」もう1つの定番。原因メーターを見分ける練習になります。
- CPU使用率が高いときの原因プロセス特定手順|top・psの見方:「どのプロセスが犯人か」を絞る調べ方の土台。FDの犯人特定にもそのまま使えます。

「Too many open files」がこわいのは、エラーの言葉(files)と本当の原因(開いている数・ソケット)が少しずれているからです。でも、/proc/<PID>/fd の数と /proc/<PID>/limits の上限を突き合わせると決めるだけで、霧はかなり晴れます。多くの場合、あなたのサーバーがおかしいわけではなく、ただ開いたものが静かに積み上がって、数の上限に当たっていただけです。
今日は、落ち着いている今のうちに主要プロセスのFD数と上限を一度見て、自分の現場の平常値を知るところからで十分です。その一手が、次の「Too many open files」を、迷路ではなく手順に変えてくれます。
ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。