Пакеты kept back в apt: почему и что с этим делать
Почему apt пишет «оставлены в неизменном виде» или «Not upgrading», чем apt-get upgrade отличается от full-upgrade и как обновить один пакет на сервере без сюрпризов.
Что значит kept back в apt
Сообщение apt «The following packages have been kept back:», в русской локализации «Следующие пакеты будут оставлены в неизменном виде:», значит одно: apt видит новую версию пакета, но запущенной команде не разрешено сделать то, что нужно для её установки. Новой версии может быть нужен пакет, которого ещё нет в системе. Она может конфликтовать с установленным пакетом. Пакет может быть заморожен через apt-mark hold. Наконец, Ubuntu может придерживать обновление намеренно, это фазовое распространение.
Чинить это командой apt full-upgrade -y вслепую не нужно. На сервере порядок другой: сначала посмотреть, что apt хочет изменить (--simulate), потом обновить нужный пакет отдельно через apt install --only-upgrade и прочитать список добавляемых и удаляемых пакетов до ответа «да».
Ниже разобрано, какая команда что имеет право делать, почему Ubuntu 24.04 и 26.04 печатают разные сообщения, и как воспроизвести все случаи на локальном тестовом репозитории.
Чем отличаются apt-get upgrade, apt upgrade и apt full-upgrade
Разница в правах. Каждая команда обновления может либо ставить новые пакеты, либо удалять старые, либо ни то ни другое. Всё остальное следует из этого.
apt-get upgrade самая осторожная. В apt-get(8) сказано прямо:
under no circumstances are currently installed packages removed, or packages not already installed retrieved and installed. New versions of currently installed packages that cannot be upgraded without changing the install status of another package will be left at their current version.
То есть установленные пакеты не удаляются ни при каких условиях, новые не ставятся. Если для новой версии нужно поставить или удалить другой пакет, пакет остаётся на текущей версии. Это и есть kept back.
apt upgrade разрешает себе на один шаг больше. Страница apt(8) в Ubuntu 24.04:
New packages will be installed if required to satisfy dependencies, but existing packages will never be removed. If an upgrade for a package requires the removal of an installed package the upgrade for this package isn't performed.
Новая зависимость будет установлена. Удаление по-прежнему запрещено, поэтому конфликт с установленным пакетом всё так же даёт kept back.
apt full-upgrade может и ставить, и удалять:
full-upgrade performs the function of upgrade but will remove currently installed packages if this is needed to upgrade the system as a whole.
В apt-get то же самое называется dist-upgrade. В исходном коде apt обе команды, apt full-upgrade и apt-get dist-upgrade, вызывают одну функцию DoDistUpgrade с флагом ALLOW_EVERYTHING. Man-страница apt-get(8) добавляет важную деталь: при конфликте apt старается обновить более важные пакеты за счёт менее важных, поэтому dist-upgrade может удалить какие-то пакеты.
Почему apt upgrade и apt-get upgrade ведут себя по-разному, если это один и тот же apt? Потому что поведение задаёт параметр APT::Get::Upgrade-Allow-New. Бинарник apt включает его по умолчанию, а apt-get нет. В коде apt 2.8 для Ubuntu 24.04 это строка _config->CndSet("Binary::apt::APT::Get::Upgrade-Allow-New", true);. Отсюда частая ситуация: sudo apt upgrade обновил пакет, а скрипт с apt-get upgrade на соседнем сервере оставил его как был.
Почему Ubuntu 26.04 пишет Not upgrading вместо kept back
В Ubuntu 26.04 стоит apt 3.2, а в 24.04 apt 2.8. На 8 ноября 2026 года Launchpad показывает в разделе updates для noble версию 2.8.4ubuntu0.1, для resolute версию 3.2.1ubuntu0.1. Свою версию смотрите командой:
apt --versionНовый интерфейс команды apt появился в ветке разработки 2.9.0 (12 апреля 2024 года): цвета, колонки, удаляемые пакеты в конце списка. Стабильная серия 3.0 началась 4 апреля 2025 года. Вместе с интерфейсом поменялись заголовки. В исходном коде apt 3.2 выбор такой: если APT::Output-Version меньше 30, печатается старый заголовок, иначе новый.
- старый заголовок:
The following packages have been kept back:, по-русскиСледующие пакеты будут оставлены в неизменном виде: - новый заголовок:
Not upgrading:, по-русскиПропуск обновления: - старая итоговая строка содержит
to remove and ... not upgraded. - новая итоговая строка содержит
Removing: ..., Not Upgrading: ...
Какой формат получит команда, зависит от бинарника. По коду apt 3.2 бинарник apt берёт за CLI-версию версию самого пакета, поэтому получает формат 3.0 и пишет «Not upgrading:». Остальные бинарники, включая apt-get, получают версию вида 0.NN и сохраняют старый заголовок. Значит, на 26.04 apt upgrade и apt-get upgrade описывают одну и ту же ситуацию разными словами. На 24.04 строки «Not upgrading:» в apt нет совсем, там обе команды печатают старый заголовок.
Русская строка «Следующие пакеты будут оставлены в неизменном виде:» взята из файла перевода apt po/ru.po, где она стоит переводом для The following packages have been kept back:. Её печатает apt 2.8 на Ubuntu 24.04 и apt-get на apt 3.x. Команда apt из apt 3.x вместо неё пишет «Пропуск обновления:». Русский текст появится, только если в системе установлена русская локализация. Если вы ищете эти сообщения в логах или в выводе скриптов, учитывайте все четыре варианта. Ещё надёжнее запускать скрипты с LC_ALL=C, чтобы вывод не зависел от языка системы.
Есть и отличие глубже текста. Начиная с apt 3.1.10 (25 октября 2025 года) новый решатель зависимостей включён по умолчанию для CLI-версий 0.31, 1.21, 2.11 и 3.1, то есть и для apt-get из apt 3.2. В apt 2.8 такого умолчания нет. Поэтому одна и та же команда на 24.04 и 26.04 может предложить разный план. Проверяйте план на той машине, где будете обновлять, а не на соседней.
Как воспроизвести kept back на тестовом репозитории
Лучше один раз увидеть все случаи на безвредных пакетах, чем разбираться на рабочем сервере. Соберём локальный репозиторий с двумя версиями демо-пакетов. Делайте это на тестовой машине или на свежем VPS. Понадобится apt-ftparchive из пакета apt-utils и dpkg-deb, который уже есть в системе.
sudo apt update
sudo apt install -y apt-utils
sudo install -d -o "$USER" /srv/keptback-demo
mkdir -p ~/keptback-buildДве функции на время сессии. mkpkg собирает пустой пакет с нужным именем, версией и одной строкой зависимостей. reindex пересобирает индекс репозитория.
mkpkg() {
d="$HOME/keptback-build/${1}_${2}"
mkdir -p "$d/DEBIAN"
chmod 755 "$d" "$d/DEBIAN"
printf 'Package: %s\nVersion: %s\nArchitecture: all\nMaintainer: Demo <demo@example.com>\nDescription: kept-back demo\n' "$1" "$2" > "$d/DEBIAN/control"
if [ -n "$3" ]; then printf '%s\n' "$3" >> "$d/DEBIAN/control"; fi
dpkg-deb --build --root-owner-group "$d" /srv/keptback-demo/
}
reindex() {
(cd /srv/keptback-demo && apt-ftparchive packages . > Packages && apt-ftparchive release . > Release)
}Права 755 задаются явно, чтобы результат не зависел от вашего umask. Подключаем репозиторий. Опция trusted=yes отключает проверку подписи, поэтому используйте её только для такого локального теста.
echo 'deb [trusted=yes] file:/srv/keptback-demo ./' | sudo tee /etc/apt/sources.list.d/keptback-demo.listПервая версия всех пакетов. demo-old нужен только для конфликта, demo-held замораживаем сразу.
mkpkg demo-newdep 1.0
mkpkg demo-clash 1.0
mkpkg demo-old 1.0
mkpkg demo-held 1.0
reindex
sudo apt update
sudo apt install -y demo-newdep demo-clash demo-old demo-held
sudo apt-mark hold demo-held
apt-mark showholdapt-mark showhold должен вывести demo-held. Теперь публикуем вторые версии: demo-newdep 2.0 требует новый пакет demo-lib, demo-clash 2.0 конфликтует с demo-old, demo-held 2.0 просто новее.
mkpkg demo-lib 1.0
mkpkg demo-newdep 2.0 'Depends: demo-lib'
mkpkg demo-clash 2.0 'Conflicts: demo-old'
mkpkg demo-held 2.0
reindex
sudo apt updateЧто покажет каждая команда
Сравниваем три команды в режиме симуляции. Ключ -s (--simulate) в apt-get(8) описан как «No action; perform a simulation of events that would occur based on the current system state»: ничего не устанавливается и не удаляется, поэтому все три команды можно запускать подряд над одним и тем же состоянием. LC_ALL=C выводит сообщения на английском, чтобы их было проще сравнить с цитатами выше.
LC_ALL=C apt-get -s upgrade
LC_ALL=C apt -s upgrade
LC_ALL=C apt -s full-upgradeПо документации картина должна быть такой.
demo-newdep:apt-get upgradeоставляет его, потому что для версии 2.0 нужно установить новый пакетdemo-lib.apt upgradeиapt full-upgradeставятdemo-libи обновляют пакет.demo-clash:apt-get upgradeиapt upgradeоставляют его, потому что версия 2.0 требует удалитьdemo-old, а удалять им запрещено. Право удалитьdemo-oldесть только уapt full-upgrade. Сделает ли он это или оставит пакет, решает решатель зависимостей, поэтому смотрите на список удаляемых пакетов в выводе.demo-held: ни одна команда его не обновит. По apt-mark(8) hold «will prevent the package from being automatically installed, upgraded or removed».
На 24.04 обе команды печатают заголовок kept back. На 26.04 apt пишет Not upgrading:, а apt-get старый заголовок. Всё перечисленное выше выведено из man-страниц и исходного кода apt. Решатель apt 3.x может на 26.04 предложить другой план, чем apt 2.8 на 24.04, поэтому истиной считайте вывод на своей машине.
Как безопасно обновить пакет, который apt оставил
На сервере не нужно разрешать всё сразу. Обновляйте оставленные пакеты по одному.
Сначала симуляция для конкретного пакета:
LC_ALL=C apt-get -s install --only-upgrade demo-newdepКлюч --only-upgrade описан в apt-get(8): вместе с install он ставит обновления только для уже установленных пакетов и игнорирует просьбы установить новые. Он работает и с apt. Важная оговорка: он не даёт install поставить сам пакет, если его не было, но зависимости новой версии всё равно могут быть установлены или удалены. В нашем примере план включит установку demo-lib. Если план устраивает, выполняем по-настоящему:
sudo apt install --only-upgrade demo-newdepНе добавляйте -y. Прочитайте список новых пакетов и особенно список удаляемых, и только потом отвечайте «да». В apt-get(8) про -y сказано, что apt прервётся в нежелательной ситуации: «such as changing a held package, trying to install an unauthenticated package or removing an essential package». Удаление обычного пакета в этом перечне не названо, так что рассчитывать, что -y вас остановит, не стоит.
Конфликт разбирается так же:
LC_ALL=C apt-get -s install --only-upgrade demo-clashЗдесь в плане ищите удаление demo-old. Если apt хочет его удалить, решите, нужен ли он вам. Если нужен, не обновляйте demo-clash, пока не разберётесь, чем его заменить. Замороженный пакет обновляется только после sudo apt-mark unhold demo-held. Заморозку ставят не просто так, поэтому сначала выясните, кто и зачем её поставил.
Перед большим обновлением пройдите чеклист обслуживания Linux-сервера.
Почему ядро Linux чаще всего остаётся в kept back
Самый частый реальный случай kept back на Ubuntu это метапакеты ядра: linux-generic, linux-image-generic, linux-headers-generic. Причина в том, как они устроены. linux-generic зависит от linux-image-generic и linux-headers-generic строго той же версии. linux-image-generic зависит от пакета, в имени которого записан номер ABI (application binary interface, двоичный интерфейс ядра), например linux-image-7.0.0-42-generic. Новое ядро с новым ABI означает пакет с новым именем, то есть новую зависимость. Именно такую зависимость apt-get upgrade не ставит, поэтому метапакеты остаются на старой версии, а apt upgrade их обновляет. Посмотреть цепочку на своём сервере:
apt-cache depends linux-generic linux-image-generic
apt-cache policy linux-genericУ каждого нового ядра своё имя пакета, поэтому старые ядра не заменяются, а накапливаются в /boot. Как безопасно удалить лишние, описано в руководстве как очистить старые ядра в Ubuntu. На Ubuntu 24.04 серверная установка по умолчанию использует GA-ядро (general availability, исходное ядро релиза), а ветка HWE (hardware enablement) с метапакетом linux-generic-hwe-24.04 ставится по желанию. Разница описана в статье HWE или GA: какое ядро ставить на Ubuntu Server. Новое ядро заработает только после перезагрузки. Если обновления ставятся автоматически, сверьте настройки с руководством по unattended-upgrades.
Пакет оставлен из-за фазового обновления
Фазовое обновление (phasing) значит, что Ubuntu выдаёт новую версию пакета сначала части машин и расширяет круг, если проблем нет. Такой пакет тоже выглядит как оставленный. Документация Ubuntu Server говорит, что делать с этим ничего не нужно: «you can safely ignore it», пакет обновится сам, когда его признают безопасным, а обновления безопасности не проходят через фазы никогда. Начиная с apt 2.7.11 такие пакеты выводятся отдельным списком: в apt 2.8 под заголовком The following upgrades have been deferred due to phasing:, в apt 3.x под Not upgrading yet due to phasing: (по-русски Обновление отложено из-за поэтапного распространения:). Подробности и способ отключить фазы есть на странице Ubuntu About apt upgrade and phased updates.
Как обновляет Proxmox VE
У Proxmox VE своя рекомендация, и она однозначная. В разделе «System Software Updates» руководства администратора (документация версии 9.2.13) даны две команды:
apt update
apt full-upgradeОбоснование в документации такое: «apt full-upgrade can also remove existing packages to satisfy dependencies if needed, while apt upgrade cannot». И предупреждение: «performing an apt upgrade may result in a partially upgraded or broken package state». То есть на хосте Proxmox apt upgrade может оставить систему обновлённой наполовину. Это правило Proxmox для его хостов. На обычном сервере Ubuntu решение то же, что выше: симуляция и чтение плана.
Удалите демо-репозиторий
Сначала снимите заморозку. По apt-mark(8) hold защищает пакет и от удаления, поэтому unhold идёт первым.
sudo apt-mark unhold demo-held
sudo apt purge demo-newdep demo-lib demo-clash demo-old demo-held
sudo rm /etc/apt/sources.list.d/keptback-demo.list
sudo apt update
sudo rm -rf /srv/keptback-demo
rm -rf ~/keptback-buildЕсли какой-то демо-пакет уже был удалён, apt сообщит, что он не установлен, и продолжит. После apt update в выводе apt list --upgradable демо-пакетов быть не должно.
FAQ
Что значит «Следующие пакеты будут оставлены в неизменном виде» в apt?
Это русский перевод сообщения apt «The following packages have been kept back:». Для пакетов из списка есть новая версия, но команде не разрешено сделать то, что нужно для её установки: поставить новую зависимость, удалить конфликтующий пакет или изменить замороженный через apt-mark hold. Ещё одна причина в Ubuntu это фазовое обновление. Запустите apt-get -s install --only-upgrade <пакет> и посмотрите, что apt хочет изменить.
Почему apt upgrade обновил пакет, а apt-get upgrade его оставил?
Бинарник apt по умолчанию включает APT::Get::Upgrade-Allow-New, поэтому apt upgrade ставит новые зависимости. apt-get upgrade этого не делает: по apt-get(8) он не ставит новые пакеты и не удаляет установленные. Пакет, которому нужна новая зависимость, например метапакет ядра с новым номером ABI, остаётся на текущей версии.
Почему Ubuntu 26.04 пишет «Not upgrading:» вместо kept back?
В Ubuntu 26.04 стоит apt 3.2, где команда apt использует новый формат вывода 3.0. В нём заголовок «The following packages have been kept back:» заменён на «Not upgrading:», по-русски «Пропуск обновления:». Смысл тот же. По исходному коду apt-get в apt 3.2 сохраняет старый заголовок, а apt 2.8 в Ubuntu 24.04 печатает только старый.
Безопасно ли запускать apt full-upgrade на сервере?
apt full-upgrade может удалять установленные пакеты, если это нужно для обновления системы в целом. Это не ошибка, но удалённым может оказаться пакет, нужный вашему сервису. Запустите сначала apt -s full-upgrade, прочитайте список удаляемых пакетов и не используйте -y, пока не прочитали план. На хостах Proxmox VE документация рекомендует именно apt full-upgrade, а не apt upgrade.
Можно ли просто игнорировать kept back?
Если пакет придержан фазовым обновлением Ubuntu, да: документация Ubuntu говорит, что он обновится сам, а обновления безопасности не проходят через фазы. Если причина в новой зависимости, apt-get upgrade его так и не обновит. При конфликте его не обновит и apt upgrade. Новая версия при этом может содержать исправление уязвимости, поэтому такие пакеты обновляйте по одному через apt install --only-upgrade после симуляции.