No space left on device переводится как «на устройстве не осталось места». Программа попыталась записать данные, а файловая система отказала: кончилось место на диске или запас inode — записей о файлах. У этой ошибки код ENOSPC, и пишут её все программы одинаково: dd, оболочка, Python, Docker, база данных.
Причин три, и проверяются они тремя командами: место кончилось на самом деле (df -h), кончились inode (df -i) или место держит удалённый, но всё ещё открытый файл (lsof +L1). Ниже — каждая на живом выводе: стенд из маленьких дисков на 2 МБ и на 64 файла в Debian 12.
Три причины и чем каждую проверить
Как выглядит ошибка
Разные программы сообщают о ней по-разному, но слова в конце одни. Запишем на пустой диск в 2 МБ файл на 5 МБ, а потом попробуем дописать строку в лог из оболочки и из Python:
dd if=/dev/zero of=/data/backup.img bs=1M count=5
echo "строка лога" >> /data/app.log
python3 -c "open('/data/app.log', 'a').write('x' * 100000)"
dd: error writing '/data/backup.img': No space left on device
3+0 records in
2+0 records out
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.000936413 s, 2.2 GB/s
bash: echo: write error: No space left on device
Traceback (most recent call last):
File "<string>", line 1, in <module>
OSError: [Errno 28] No space left on device
dd успел записать 2 МБ — ровно столько, сколько было свободно, — и остановился. В Python та же ошибка приходит как OSError с номером 28.
Причина 1: кончилось место
Первая команда — df -h: сколько места на каждой файловой системе, в понятных единицах.
df -h /data
Filesystem Size Used Avail Use% Mounted on
tmpfs 2.0M 2.0M 0 100% /data
Use% 100% и Avail 0 — диск заполнен. Дальше нужно найти, что его заняло. du -sh показывает размер каждого файла и каталога, а sort -h ставит самые большие в конец:
du -sh /data/* | sort -h
0 /data/app.log
2.0M /data/backup.img
На настоящем сервере начинают с корня и спускаются вглубь: sudo du -xh --max-depth=1 / | sort -h. Ключ -x не даёт du уходить на другие диски. Частые виновники:
- логи в
/var/log, особенно журнал systemd — его ужимают командойsudo journalctl --vacuum-size=200M; - кэш пакетов, который чистит
sudo apt clean; - образы, контейнеры и кэш сборки Docker — о нём ниже;
- забытые бэкапы и дампы баз данных.
Причина 2: кончились inode
У каждого файла есть inode — запись с его владельцем, правами и адресом данных. На ext4, самой частой файловой системе Linux, число inode задаётся при её создании. Если файлов очень много, inode кончаются раньше места, и df -h показывает свободный диск. Создадим пустые файлы на диске, где inode всего 64:
mkdir /files/cache
for i in $(seq 1 100); do touch /files/cache/item$i || break; done
df -h /files
df -i /files
touch: cannot touch '/files/cache/item57': No space left on device
Filesystem Size Used Avail Use% Mounted on
tmpfs 10M 0 10M 0% /files
Filesystem Inodes IUsed IFree IUse% Mounted on
tmpfs 64 64 0 100% /files
Файлы пустые, места свободно 10 МБ, а IUse% 100% — и 57-й файл создать уже нельзя. На стенде это 64 inode, на реальных серверах так заканчиваются миллионы: кэш, файлы сессий, письма в очереди, миниатюры. Найди каталог, где файлов больше всего, — du --inodes -x / | sort -n | tail — и удали ненужные.
Причина 3: файл удалён, но открыт
Классическая ловушка: удалил огромный лог, а место не освободилось. Если файл держит открытым процесс, rm удаляет только имя, а данные остаются, пока процесс их не закроет. На стенде роль службы, которая пишет в лог, играет sleep: он держит backup.img открытым на чтение.
sleep 3600 < /data/backup.img &
rm /data/backup.img && df -h /data
Filesystem Size Used Avail Use% Mounted on
tmpfs 2.0M 2.0M 0 100% /data
Такие файлы находит lsof +L1 — это открытые файлы, у которых не осталось ни одного имени:
lsof +L1 /data
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
sleep 3362 dev 0r REG 0,417 2097152 0 5 /data/backup.img (deleted)
Процесс sleep с PID 3362 держит удалённый файл размером 2 МБ, а NLINK 0 значит, что имён у файла не осталось. Как только процесс завершится, место вернётся:
kill 3362
df -h /data
Filesystem Size Used Avail Use% Mounted on
tmpfs 2.0M 0 2.0M 0% /data
На сервере это обычно служба, которая пишет в лог, — её перезапускают через systemctl. Чтобы не попадать в эту ловушку, большой лог очищают, а не удаляют: : > /var/log/app.log обнуляет файл, и процесс продолжает писать в него же. Подробнее о процессах и сигналах — в статье про процессы.
Docker: образы и кэш сборки
Если ошибка появилась при docker build или docker pull, скорее всего, место съел сам Docker. Посмотреть, сколько занимают образы, контейнеры, тома и кэш сборки, можно командой docker system df. Удалить остановленные контейнеры, неиспользуемые сети, образы без тегов и кэш сборки — docker system prune. С ключом -a удаляются и все образы, которыми не пользуется ни один контейнер. Тома команда не трогает без --volumes, и это правильно: в томах лежат данные баз.
Ошибки, на которых спотыкаются
Ищут место не на том диске. Ошибка относится к файловой системе, куда шла запись, а не к корню. df -h /путь/к/папке показывает именно её.
Удаляют лог, который пишется прямо сейчас. Место не вернётся, пока служба не перезапустится. Лог очищают через : > файл или настраивают ротацию.
Чистят Docker с --volumes на сервере с базой. Тома с данными уйдут вместе с кэшем. Сначала посмотри docker system df -v, потом удаляй точечно.
Смотрят только df -h. Свободные гигабайты при 100% inode выглядят как загадка. Если места много, а ошибка есть, проверь df -i.
Частые вопросы
Как перевести No space left on device
«На устройстве не осталось места». Устройство здесь — файловая система, куда программа пыталась записать данные.
Что значит Errno 28 в Python
Это номер ошибки ENOSPC в Linux. OSError: [Errno 28] No space left on device значит то же самое: диск или inode кончились. Проверяй их командами df -h и df -i, как в разделах выше.
Почему место не освободилось после удаления файла
Файл открыт процессом. lsof +L1 покажет, каким именно, а перезапуск процесса вернёт место.