ENOSPC(No space left on device)

書き込みが突然「No space left on device」で止まる原因を、df だけ見ても空きがあるのに直らない罠まで含めて逆引きできる。削除済みファイルの掴みと inode 枯渇の切り分けで最短復旧できる。

応用LinuxファイルシステムinodeトラブルシューティングDocker運用最終更新: 2026-07-28
3つの要点
TL;DR
  1. ENOSPC は write(2)・open(2) 等が返すエラーで、ブロック容量の枯渇と inode の枯渇という別々の原因がある。df -h が空きを示していても inode が尽きれば発生する。
  2. 消したはずのファイルをプロセスが開いたままだと inode は解放されず、df の空きは戻らない。lsof +L1 で nlink=0 の削除済みファイルを掴むプロセスを特定し、再起動かログローテートで解放する。
  3. 診断は df -h(ブロック)と df -i(inode)を必ず両方見て、du で肥大箇所を絞り、Docker では layer・volume・build cache を prune する。予防はローテート・監視・quota。

一言でいうと(このエラーが何を意味するか)

ENOSPC は「No space left on device」に対応する POSIX のエラー番号(errno の 28)で、write(2)open(2)O_CREAT)・mkdir(2)rename(2) などがデータを書き込めなかったときにカーネルが返します。アプリ側では write: No space left on device や Node.js の Error: ENOSPC として表面化します。

重要なのは、原因が 2 種類あることです。1 つはブロック(データ本体を置く領域)の枯渇。もう 1 つは inode(ファイルのメタデータ枠)の枯渇です。ext4 などは作成時に inode 数が固定されるため、1 バイトの空きが山ほどあっても inode を使い切ればもう 1 ファイルも作れず ENOSPC になります。df -h だけを見て「空いているのに直らない」と詰まる典型がこれです。

ENOSPCとEDQUOTは別物

ディスク全体は空いていても、ユーザー/グループ quota を超えると EDQUOT(Disk quota exceeded)が返ります。メッセージが「Disk quota exceeded」なら本記事の df ではなく quota -vrepquota を見ます。文言で切り分けてください。

横にスクロール

ENOSPCをデータ容量inodeクォータ削除済みファイル保持に分けて復旧確認する手順
df -hに空きがあっても書けない場合がある。失敗パスのマウントで四種類の枯渇を分ける。

よくある原因(複数を具体的に、頻度順)

  • ログ・一時ファイルの肥大: ローテート未設定のアプリログ、journald/tmp、APT/yum キャッシュがパーティションを埋める。最頻出。
  • 削除したのに空きが戻らない: プロセスが開いているファイルを rm しても、ファイルの nlink(ハードリンク数)は 0 になるがプロセスが握るファイルディスクリプタが残る限り inode とブロックは解放されない。ログを rm したのにサーバーの空きが増えない、という症状の正体。
  • inode 枯渇: メールキュー、セッションファイル、npm の node_modules、大量の小ファイルを作るバッチが inode を食い尽くす。df -h は余裕、df -i が 100%。
  • Docker のディスク肥大: 未使用の image layer・停止コンテナ・匿名 volume・build cache が /var/lib/docker を埋める。ホストの ENOSPC の主犯になりやすい。
  • 予約ブロックの壁: ext 系は既定で 5% を root 用に予約する。一般ユーザーのプロセスは 95% の時点で ENOSPC を食う(df は使用率 95% 前後を示す)。
  • 特殊要因: inotify の watch 上限超過(ENOSPC を返すが実ディスクは無関係。エディタや webpack --watch で頻発)、スパースファイルの実書き込み、スナップショット領域の消費など。
rm しても df が変わらないのは正常な挙動

Linux の unlink はディレクトリエントリを消すだけで、開いているファイルの実体はプロセスが閉じるまで残ります。だから肥大ログを消しても、それを追記中のプロセスがいれば空きは戻りません。プロセスの再起動、または : > /path/to/log(truncate)でその場の実体を縮めるのが正攻法です。

診断の手順(切り分け方・見るべきログ/コマンド)

まずブロックと inode を両方確認します。ここを片方だけで済ませるのが最大の落とし穴です。

df -h        # ブロック容量。Use% と Mounted on を見る
df -i        # inode 使用率。IUse% が 100% なら inode 枯渇

どのマウントが満杯かを特定したら、その配下で消費元を絞ります。

# 大きいディレクトリ上位(対象FS内に限定して他マウントへ潜らない)
du -x -h --max-depth=1 /var | sort -rh | head -20

# inode枯渇時は「大きさ」でなく「ファイル数」で探す
find /var -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -20

「消したのに戻らない」を疑うときは、削除済み(nlink=0)を掴むプロセスを特定します。

# +L1 は「リンク数が1未満=削除済みだが未クローズ」のファイルだけを表示
lsof +L1
# 出力の NLINK 列が 0、SIZE/OFF が巨大なものが原因。PID を再起動 or truncate
症状df -hdf -i有力な原因次の一手
空きゼロ100%余裕ログ・キャッシュ肥大du -x で肥大箇所を特定し削除/ローテート
消しても戻らない高いまま高いまま削除済みをプロセスが保持lsof +L1 → 再起動 or truncate
空きあるのにENOSPC余裕100%inode枯渇find で小ファイル群を特定し整理
Docker周辺で発生100%(/var)どちらも有り得るlayer/volume/cache肥大docker system df → prune

Docker が絡む場合は専用の内訳コマンドが早いです。

docker system df          # image/container/volume/build cache の内訳
docker system df -v       # 個別サイズの詳細

解決と予防(対処と再発防止)

対処は「原因の種類」で分岐します。

# 1) 肥大ファイルの縮小(追記中のプロセスを止めずに実体だけ0に)
: > /var/log/huge.log            # rm ではなく truncate。fd はそのまま生きる

# 2) 削除済み保持の解放:lsof +L1 で見つけた PID を再起動、または
truncate -s 0 "/proc/<PID>/fd/<N>"   # 該当fdの実体を縮める最終手段

# 3) journald の肥大を上限付きで整理
journalctl --vacuum-size=200M

# 4) Docker の不要データを一括回収(volume も消すなら --volumes は慎重に)
docker system prune            # 停止コンテナ・未使用network・dangling image・cache
docker image prune -a          # 未参照 image を全削除

inode 枯渇は「削除」でしか回復しません。ext4 は後から inode 数を増やせず、増やすには作り直し(mkfs -N-i)が要ります。小ファイルが構造的に多いなら、inode を動的確保する XFSBtrfs への移行が根本策です。予約ブロックはデータ用途のパーティションなら tune2fs -m 1 /dev/sdXN で 5%→1% に下げて実効容量を稼げます。

再発防止の定石
  • ログは logrotate と journald の SystemMaxUse= で必ず上限を設ける
  • 監視は「容量」と「inode」を別メトリクスで、80% でアラート(100% では手遅れ)
  • ユーザー/プロジェクト単位の暴走は quota で封じ込める
  • inotify の ENOSPCfs.inotify.max_user_watchessysctl で引き上げる(ディスクとは無関係)

ファイルシステムの inode・ハードリンク・unlink の内部動作はOS、コンテナのレイヤ管理と /var/lib/docker 肥大の背景はDevOps、テーブルスペースや WAL でディスクを食う DB 側の枯渇はデータベースを参照してください。

試験・面接での頻出ポイント
  • ENOSPC は errno 28。ブロック枯渇と inode 枯渇は別原因で、後者は df -h に空きがあっても起きる
  • 削除済みファイルは開いているプロセスがある限り解放されない(unlink は nlink を減らすだけ)。lsof +L1 で特定
  • 診断は df -h と df -i を必ず併用。inode は「大きさ」でなく「ファイル数」で追う
  • ext4 の inode 数は作成時固定で後から増やせない。XFS は動的確保

エラー辞典の記事ガイド

ENOSPC(No space left on device)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

Linux

比較で見る軸

難易度: advanced / カテゴリ: エラー辞典 / タグ数: 6

導入後に効く点

消したはずのファイルをプロセスが開いたままだと inode は解放されず、df の空きは戻らない。lsof +L1 で nlink=0 の削除済みファイルを掴むプロセスを特定し、再起動かログローテートで解放する。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
エラー辞典
タグ数
6

判断チェックリスト

  • 自社の用途が「Linux / ファイルシステム」に近いか確認する。
  • 強みである「ENOSPC は write(2)・open(2) 等が返すエラーで、ブロック容量の枯渇と inode の枯渇という別々の原因がある。df -h が空きを示していても inode が尽きれば発生する。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

LinuxファイルシステムinodeトラブルシューティングDocker