'bash: fork: retry: Resource temporarily unavailable' を修正する — Linux のユーザープロセス数上限

intermediate🐧 Linux2026-05-05| Linux (Ubuntu, Debian, CentOS, RHEL, Rocky Linux) — PAM/ulimit を持つすべてのディストリビューション。多数の並行プロセスを実行するサーバー(Web サーバー、CI ランナー、Java アプリ)で発生しやすい

Error Message

bash: fork: retry: Resource temporarily unavailable
#ulimit#fork#プロセス#リソース制限#pam

何が起きているか

スクリプトを実行したり、サービスを起動したり、サーバーにSSH接続しようとしたりすると、突然すべてがこのエラーで止まってしまいます:

bash: fork: retry: Resource temporarily unavailable
bash: fork: Resource temporarily unavailable

新しいプロセスが起動できません。SSH接続はタイムアウトし、cronジョブは無言で失敗します。RAMは十分あり、CPUはアイドル状態で、サーバーは明らかに動いているのに、何もforkできません。**最大ユーザープロセス数(nproc)**の上限に達してしまっているのです。

Linuxは各ユーザーが任意の時点で所有するプロセス数を追跡しています。その上限に達すると、fork()EAGAINを返します。これがまさに今起きていることです。

まず診断する

現在の制限を確認する

# 現在のシェルセッションの制限を確認
ulimit -a

# 最大ユーザープロセス数を確認
ulimit -u

古いシステムではデフォルト値が非常に低く設定されています:

max user processes              (-u) 1024

最近のsystemdディストリビューションはデフォルト値が高め(Ubuntu 22.04では63503など)ですが、専用ユーザーで動作するサービスは多くの場合、PAMの低い制限値を継承します。場合によってはまだ1024のままです。

影響を受けているユーザーが実行中のプロセス数を数える

# 'www-data' を実際のユーザー名に置き換えてください
ps -u www-data --no-header | wc -l

# またはプロセス数でソートして全ユーザーを表示
ps aux | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

この数がulimitの値以上または近い場合、問題が確認できます。

PAMで設定された制限(実際の上限)を確認する

grep -r nproc /etc/security/limits.conf /etc/security/limits.d/

次のような内容が表示されることがあります:

*    soft    nproc    1024
*    hard    nproc    4096

soft制限はプロセスが開始時に持つ値です。hard制限はプロセスが自分で引き上げられる最大値です。両方が低いことが原因です。

systemdが強制する制限を確認する(サービス向け)

注意点があります:影響を受けているプロセスがsystemdサービスの場合、/etc/security/limits.confはまったく適用されないことが多く、systemdが独自に制限を管理します。

# 実行中のサービス(例:nginx)の有効な制限を確認
systemctl show nginx | grep -i task

# または特定のPIDの /proc を確認
cat /proc/$(pgrep -o nginx)/limits | grep processes

修正する

方法1:現在のセッションの制限を引き上げる(一時的)

簡単なテストや一回限りのスクリプトに適しています。シェルを閉じると同時にリセットされます。

# soft制限を8192に引き上げる
ulimit -u 8192

# 確認
ulimit -u

引き上げられるのはhard制限までです。hard制限の引き上げにはroot権限が必要です。

方法2:PAM経由で恒久的な制限を設定する(ログインユーザーとデーモン向け)

/etc/security/limits.d/に新しいファイルを追加します。limits.confを直接編集するより整理されています:

sudo nano /etc/security/limits.d/99-nproc.conf

以下の行を追加します(実際のワークロードに合わせて値を調整してください):

# 全ユーザーのnprocを引き上げる
*    soft    nproc    65536
*    hard    nproc    65536

# または特定のユーザーを対象にする
www-data    soft    nproc    32768
www-data    hard    nproc    32768

# rootは * ワイルドカードから除外されることが多いため、必要であれば明示的に設定する
root    soft    nproc    unlimited
root    hard    nproc    unlimited

**重要:**PAMの制限は新しいログインセッションにのみ適用されます。既存のプロセスは古い制限を維持します。変更を反映させるにはサービスを再起動するか、一度ログアウトして再ログインしてください。

方法3:systemdサービスの制限を修正する

PAMの制限はsystemdが起動したサービスには届きません。ドロップインファイルを使ってサービスごとに上書きします:

sudo systemctl edit nginx

以下を追加します:

[Service]
TasksMax=infinity
LimitNPROC=65536

その後、リロードして再起動します:

sudo systemctl daemon-reload
sudo systemctl restart nginx

すべてのsystemdサービスのグローバルデフォルトを引き上げるには、/etc/systemd/system.confを編集します:

sudo nano /etc/systemd/system.conf
[Manager]
DefaultTasksMax=infinity
sudo systemctl daemon-reload

方法4:プロセスリークを確認する(根本原因を修正する)

制限を引き上げるのは症状への対処です。ゾンビプロセスや無限に子プロセスを生成するループが真の問題であれば、制限を上げても長くはもちません。

# ゾンビプロセスを一覧表示
ps aux | awk '$8 == "Z"'

# 特定ユーザーのプロセス数が増え続けているか監視
watch -n 2 "ps -u myuser --no-header | wc -l"

# 子プロセスを大量に生成している親プロセスを探す
ps -eo pid,ppid,user,comm | awk '{print $2}' | sort | uniq -c | sort -rn | head -5

カウントが増え続けて一向に減らない場合はリークです。アプリケーションを修正してください。

修正が効いたか確認する

# limits.confの変更を適用後、新しいセッションを開いて確認:
ulimit -u

# systemdサービスの場合、新しい制限が有効になっているか確認:
cat /proc/$(pgrep -o nginx)/limits | grep processes

# ストレステスト — 100個のバックグラウンドプロセスを起動:
for i in $(seq 1 100); do sleep 1 & done
# 'Resource temporarily unavailable' が出ずに完了するはず
jobs | wc -l
kill $(jobs -p)

クイックリファレンス:ディストリビューション別の一般的なデフォルト値

  • CentOS 6 / RHEL 6:非rootユーザーのデフォルトnproc = 1024 — JavaアプリケーションやRuby on Railsのデプロイメントは常にこの値を超えてしまいます
  • CentOS 7 / RHEL 7+/etc/security/limits.d/20-nproc.confが4096で同梱されています — limits.confではなくこの特定のファイルを確認して上書きしてください
  • Ubuntu 20.04+:systemd管理で、TasksMaxのデフォルトはシステム最大値の15%(一般的なVPSでは約4915)— 高い同時実行性を持つサービスはまだ上限に達します
  • Dockerコンテナ:デフォルトではホストのulimitを継承します。多数の並行プロセスを持つコンテナを実行する際は--ulimit nproc=65535:65535を渡してください

実際によくある原因:CIランナー

最もよく見かける場面は、JenkinsやGitLab Runnerのインスタンスで20並列ビルドを実行している場合です。各ジョブはシェル、コンパイラ、テストスイートをforkします。1ジョブあたり60以上のプロセスが、20ジョブ分で掛け合わされ、数秒で1024を超えてしまいます。

サービスを実行するユーザーに対しては、nprocを少なくとも65536に設定してください。コストはゼロです。これはメモリの予約ではなく、カーネルの計算上の制限に過ぎません。

もう一点:PAMは設定されているがsystemdがサービスを管理しているシステムでは、limits.confを修正するだけでは解決しません。両方の設定が必要です。

Related Error Notes