Сообщение tar: Exiting with failure status due to previous errors само по себе почти никогда не является корнем проблемы. Это финальная строка, которой tar сообщает: раньше по ходу упаковки уже были ошибки или предупреждения, из-за которых команда завершилась с ненулевым статусом. На практике именно эта строка чаще всего всплывает в логах backup-скриптов, CI/CD-пайплайнов, deploy-хуков и cron-задач на Debian и Ubuntu.
Типичная ошибка администратора — смотреть только на последнюю строку. Но лечить нужно не её, а первое проблемное сообщение выше в выводе. Именно там обычно встречаются ключевые фразы вроде Permission denied, file changed as we read it, Cannot stat, No such file or directory, socket ignored или Removing leading '/'. Часть из них безобидна, часть ломает backup, а часть особенно опасна в deploy-сценариях, когда архив формально создан, но неполон.
Отдельно важный момент: в автоматизации интересен не только текст ошибки, но и код возврата. Если скрипт использует set -e, пайплайн может упасть даже тогда, когда архив создался, а проблема была нефатальной. Поэтому диагностика должна опираться на stderr, exit code и контекст задачи.
Для backup это особенно критично: «архив создался» не означает «резервная копия пригодна к восстановлению». Для deploy часто безопаснее прервать публикацию, чем молча исключить часть файлов приложения и получить полурабочий релиз.
Что на самом деле означает эта ошибка у tar
tar завершает работу разными кодами возврата. Упрощённо:
0— успех без значимых проблем;1— были предупреждения, различия или некритичные ошибки в зависимости от режима;2— фатальная ошибка.
Но есть нюанс: интерпретация зависит от конкретной операции — создание архива, распаковка, сравнение, чтение из потока. Поэтому в боевых скриптах не стоит полагаться на общую память о кодах возврата. Лучше проверять поведение именно вашей команды с вашими флагами.
Фраза Exiting with failure status due to previous errors означает буквально следующее: в ходе работы уже были сообщения, которые tar посчитал ошибками, и теперь процесс завершается с ошибочным статусом. То есть главный вопрос не «почему tar ругается», а «какая первая проблема в выводе привела к ненулевому завершению».
Если в логе вы видите только последнюю строку от tar, значит логирование в скрипте организовано плохо. Для поиска причины нужен полный stderr, а не хвост из одной строки.
Самые частые причины на Debian и Ubuntu
Проблемы с правами: tar permission denied
Самый частый сценарий — архиватор запущен от пользователя, у которого нет прав читать часть файлов или заходить в один из каталогов дерева. Это типично для backup домашних директорий, каталогов приложений, дампов БД, логов и файлов, созданных другим сервисом.
Например, вы архивируете /var/www, а внутри лежат файлы, созданные root, www-data или отдельным deploy-пользователем. Даже если большинство файлов читается, одной закрытой директории достаточно, чтобы tar выдал Cannot open: Permission denied или Cannot stat: Permission denied, а затем завершился общей строкой об ошибке.
Проверять нужно не только права на сам файл, но и права на проход по каждому родительскому каталогу. Очень частая ловушка — у файла права на чтение есть, а на один из каталогов по пути нет бита исполнения для текущего пользователя.
id
namei -om /var/www/project/storage
sudo -u backupuser test -r /var/www/project/.env && echo ok
sudo -u backupuser test -x /var/www/project/storage && echo ok
Если backup должен работать без root, лучше заранее выстроить модель прав: выделенный пользователь, групповое чтение нужных директорий, ACL при необходимости, отдельные каталоги для временных файлов и дампов.
Файлы меняются во время чтения: file changed as we read it
Вторая по популярности причина — вы архивируете «живой» каталог, в котором приложение продолжает писать логи, кэш, сессии, очереди, собранные ассеты или временные файлы. Пока tar читает файл, тот меняется, и архиватор честно сообщает: file changed as we read it.
Это особенно характерно для каталогов storage, var, tmp, cache, для логов в /var/log, для директорий с пользовательскими загрузками при активном трафике и для релизных каталогов во время deploy, если в них ещё идёт сборка или копирование.
Такое сообщение не всегда означает катастрофу, но всегда означает, что архив не является атомарным снимком состояния. Для backup это риск несогласованности. Для deploy-архива — риск нестабильного содержимого от запуска к запуску.
В продакшене правильный путь не «подавить предупреждение», а перестать архивировать изменяемые области вместе с кодом или данными, для которых важна консистентность.
Если у вас проект уже вырос из простого архива в полноценную схему резервного копирования, посмотрите также практики с инкрементами и верификацией в статье про backup в S3 через restic и borg.
Это особенно заметно на серверах, где одновременно крутятся приложение, планировщик задач и фоновые воркеры: чем больше параллельных процессов, тем выше шанс поймать гонку на чтении файлов.

Файлы исчезли по пути: Cannot stat и No such file or directory
Если во время обхода дерева файл успел удалиться, переехать или переименоваться, tar может выдать Cannot stat или No such file or directory. Это обычная история для временных файлов, ротации логов, релизных каталогов во время очистки старых версий и параллельных deploy-процессов.
В backup-задачах это чаще всего говорит о гонке. В deploy-задачах — о плохой последовательности шагов: например, один процесс ещё пакует релиз, а другой уже чистит workspace.
В архив попали сокеты, proc, sys, tmpfs и прочие специальные сущности
Если бездумно архивировать системные каталоги целиком, можно поймать массу странных сообщений. Unix-сокеты, псевдофайловые системы, bind mount, временные файлы и runtime-каталоги обычно не нужно включать в backup как есть.
/proc;/sys;/run;/devбез явного понимания задачи;- сокеты PHP-FPM, MySQL, Redis, Gunicorn, Node.js и других сервисов.
Такие объекты либо не читаются нормально, либо не имеют смысла в архиве, либо создаются системой заново после восстановления.
Как искать настоящую причину, а не лечить симптом
Первое правило: запускайте команду так, чтобы видеть полный stderr. В cron и CI это особенно важно. Если вывод проглатывается или сохраняется только последняя строка, вы теряете главный источник диагностики.
tar -czf backup.tar.gz /var/www/project 2>tar.err
cat tar.err
Полезно сразу сохранить код возврата:
tar -czf backup.tar.gz /var/www/project 2>tar.err
rc=$?
echo $rc
cat tar.err
Если нужно быстро выделить проблемные места, ищите характерные шаблоны:
grep -E "Permission denied|Cannot stat|No such file|file changed as we read it" tar.err
Если ошибка проявляется только в автоматизации, но не воспроизводится вручную, сравнивайте окружение:
- какой пользователь запускает задачу;
- какая текущая директория;
- какой
PATHв cron, systemd или CI; - не меняются ли файлы параллельным процессом;
- не очищается ли временный каталог раньше времени.
Для deploy-скриптов полезно временно включить трассировку shell и логировать список файлов перед упаковкой. Очень часто проблема обнаруживается в неправильном пути, а не в tar.
set -x
pwd
whoami
find . -maxdepth 3 -type f | sed -n '1,50p'
Как исправить tar permission denied
Если причина в правах, решений обычно четыре: запуск от нужного пользователя, корректировка владельца, настройка групповых прав или точечные ACL. Выбор зависит от сценария.
Для backup сервисных данных чаще всего оправдан запуск через sudo от root, но с аккуратным списком каталогов, а не с архивированием половины файловой системы. Для deploy наоборот лучше, чтобы упаковка шла от обычного deploy-пользователя, а структура релиза изначально создавалась с предсказуемыми правами.
Проверьте владельца и режимы доступа:
ls -la /var/www/project
find /var/www/project -maxdepth 3 ! -readable -ls
Если проблема в отдельных каталогах, исправляйте адресно:
chgrp -R deploy /var/www/project
chmod -R g+rX /var/www/project
Если нужен доступ без смены владельца, используйте ACL:
setfacl -R -m u:backupuser:rX /var/www/project
setfacl -R -m d:u:backupuser:rX /var/www/project
Но не превращайте это в хаос. Если backup регулярно упирается в права, значит архитектура хранения файлов требует нормализации. Иначе через месяц появится очередная «случайная» ошибка уже в другом каталоге.
Что делать с file changed as we read it
Здесь главное — понять, архивируете ли вы статичное содержимое или «живую» рабочую директорию. Для кода, шаблонов, конфигов и собранного релиза обычно можно добиться стабильности. Для логов, сессий и временных файлов — нет, и это нормально: их просто не нужно паковать вместе с остальным.
Практические варианты:
- исключить изменяемые каталоги из архива;
- перед backup остановить запись в нужную директорию;
- сделать снимок файловой системы и архивировать уже его;
- разделить backup кода и backup данных;
- в deploy архивировать только артефакт сборки, а не рабочее дерево приложения.
Для типичного веб-приложения разумно исключать кэш, логи, временные файлы, сокеты и локальные зависимости, если они воспроизводимы из lock-файлов или CI-артефактов.
tar -czf release.tar.gz . --exclude=.git --exclude=node_modules --exclude=var/cache --exclude=var/log --exclude=tmp
Если важна именно консистентная резервная копия пользовательских данных, архивирование активного каталога — компромиссное решение. Лучше сначала получить согласованное состояние: например, отдельный дамп БД, короткая «заморозка» приложения, снапшот тома или копия через staging-каталог.
Сообщение
file changed as we read it— не просто косметическое предупреждение. Оно означает, что содержимое архива может не соответствовать ни начальному, ни конечному состоянию каталога.
Надёжный подход для backup на Debian/Ubuntu
Если задача — резервное копирование, не пытайтесь одним вызовом tar упаковать и код, и базу, и runtime-файлы, и системные каталоги. Это почти гарантированный путь к нестабильным архивам и трудным восстановлениям.
Намного надёжнее разбить backup на слои:
- отдельно конфигурация;
- отдельно код или релизный артефакт;
- отдельно пользовательские загрузки;
- отдельно дамп базы данных;
- отдельно список пакетов и системных настроек, если это действительно нужно.
Тогда и диагностика проще: если падает архив загрузок, вы не теряете backup конфигов; если меняются runtime-файлы, это не ломает упаковку релиза.
Хорошая практика — сначала собрать staging-каталог с нужным составом, а уже потом архивировать его. Это особенно полезно, если дерево источника шумное и в нём много лишнего.
mkdir -p /tmp/backup-stage
rsync -a --delete --exclude='.git' --exclude='var/cache' --exclude='var/log' /var/www/project/ /tmp/backup-stage/project/
tar -czf /backup/project-$(date +%F-%H%M%S).tar.gz -C /tmp/backup-stage project
Да, это требует чуть больше места и шагов, но делает результат предсказуемым. А в задачах backup предсказуемость важнее минимализма. Если вы строите инфраструктуру под регулярные резервные копии и фоновые задачи, удобнее делать это на отдельном VDS, где проще контролировать права, расписание и объём хранилища.
Когда в backup участвуют базы данных, не смешивайте их с файловым архивом. Для PostgreSQL отдельно пригодится материал про PITR и WAL-архивацию PostgreSQL.
После сборки архива полезно сразу проверять его тестовой распаковкой в отдельный каталог, чтобы не узнать о повреждении уже во время восстановления.
Если на проекте важна не только целостность backup, но и доверие к точке восстановления, имеет смысл отдельно использовать SSL-сертификаты для защищённого доступа к панелям, репозиториям и внутренним сервисам, через которые проходят операции сопровождения.
Надёжный подход для deploy
В deploy-сценариях проблема обычно связана с тем, что архив создаётся не из чистого build-артефакта, а из рабочего каталога, где одновременно живут исходники, кэш, временные файлы, локальные секреты, результаты прошлых сборок и служебные каталоги CI.
Если вы пакуете релиз для доставки на сервер, архивируйте только то, что должно оказаться в продакшене. Не всё подряд из текущей директории, а заранее подготовленный набор файлов.
Нормальная последовательность выглядит так:
- создать чистый каталог сборки;
- скопировать в него только нужные файлы;
- выполнить сборку ассетов и установку зависимостей в этом каталоге;
- проверить состав;
- создать архив из build-каталога;
- доставить и распаковать его как новый релиз.
Тогда сообщения вроде file changed as we read it обычно исчезают сами собой, потому что во время упаковки содержимое больше никто не трогает.
rm -rf build
mkdir build
rsync -a --exclude='.git' --exclude='storage/logs' --exclude='tmp' ./ build/
cd build
tar -czf ../release.tar.gz .
Если deploy идёт на том же сервере, не архивируйте текущий активный релиз с живыми логами и сокетами. Либо используйте отдельный каталог сборки, либо публикуйте через новую директорию релиза и атомарное переключение симлинка после проверки.

Какие предупреждения можно игнорировать, а какие нельзя
Это один из самых частых практических вопросов. Короткий ответ: игнорировать можно только то, смысл чего вы точно понимаете и заранее заложили в процесс.
Обычно безопасно трактуются как ожидаемые:
- исключённые по шаблону пути;
- сообщения о ведущем слеше при упаковке абсолютных путей;
- отдельные служебные предупреждения, не влияющие на целостность целевых данных.
Почти всегда требуют разбирательства:
Permission denied;Cannot statдля важных файлов;No such file or directory, если путь должен существовать;file changed as we read itна данных, для которых нужна консистентность;- ошибки чтения ввода-вывода.
Если backup или deploy — часть автоматизации, лучше не строить логику на принципе «проглотим всё, что написал tar». Намного надёжнее явно определить допустимые предупреждения и завершать задачу на всё остальное.
Мини-чеклист для быстрого разбора инцидента
- Посмотрите не последнюю строку, а первое сообщение об ошибке выше.
- Проверьте код возврата команды.
- Уточните, каким пользователем запущен backup или deploy.
- Проверьте права на файл и на все каталоги по пути.
- Выясните, не меняется ли файл в момент чтения.
- Уберите из архива логи, кэш, сокеты и временные каталоги.
- Не архивируйте рабочее дерево приложения, если можно архивировать build-артефакт.
- Для backup отделите код, конфиги, загрузки и БД.
- После исправления проверьте не только создание архива, но и тестовую распаковку.
Итог
tar: Exiting with failure status due to previous errors в Debian и Ubuntu — это не диагноз, а индикатор того, что выше по логу уже была конкретная причина сбоя. Чаще всего это tar permission denied, гонки на изменяющихся файлах, исчезающие временные объекты или попытка архивировать неподходящие системные каталоги.
Для backup правильная стратегия — собирать консистентный набор данных и не мешать в один архив код, runtime и живые данные. Для deploy — паковать только чистый артефакт сборки, а не рабочую директорию. Как только процесс становится предсказуемым, ошибка tar почти всегда исчезает сама, потому что исчезают её реальные причины.
Если запомнить одну мысль, то вот она: лечите не финальную строку tar, а первый проблемный путь в stderr. Это экономит часы отладки и делает backup и deploy заметно надёжнее.


