Ошибки NO_PUBKEY, Conflicting values set for option Signed-By и похожие сбои во время apt update обычно появляются после добавления стороннего репозитория, ручного импорта GPG-ключа по старым инструкциям или миграции системы между версиями Debian и Ubuntu.
На практике проблема почти всегда сводится к одному из трёх сценариев: ключа нет, ключ лежит не там, где его ждёт APT, или один и тот же репозиторий описан несколькими способами с разными параметрами Signed-By.
Отдельная сложность в том, что старые гайды до сих пор советуют использовать apt-key. Этот способ считается устаревшим: он смешивает доверие ко всем ключам в общей связке и сильно усложняет аудит.
Современный подход проще и безопаснее: хранить ключи репозиториев в отдельных файлах keyring и явно привязывать каждый источник пакетов к своему ключу через параметр Signed-By.
Если действовать хаотично и удалять файлы из /etc/apt наугад, небольшая проблема быстро превращается в цепочку конфликтов. Поэтому ниже пойдём по правильному порядку: сначала выясним, какой именно репозиторий ломается, затем проверим формат его описания, после этого приведём ключи к актуальной схеме и только в конце повторно проверим обновление индекса.
Инструкция подходит для Debian 11/12 и Ubuntu 20.04/22.04/24.04, а также для большинства производных систем с обычным APT. Если вы сопровождаете рабочий сервер на VDS, такой аккуратный порядок особенно важен: ошибка в источниках пакетов легко ломает автоматические обновления и деплой.
Что означают ошибки NO_PUBKEY и Signed-By conflict
NO_PUBKEY означает, что APT получил метаданные репозитория, подписанные ключом, которого нет среди доверенных ключей для этого источника. Обычно в сообщении выводится длинный идентификатор ключа, например NO_PUBKEY ABCD1234EF567890.
Это не всегда значит, что ключ вообще отсутствует в системе. Иногда он есть, но репозиторий настроен через Signed-By, и APT смотрит только в конкретный файл keyring, а не во все глобальные хранилища.
Ошибка Conflicting values set for option Signed-By означает, что для одного и того же репозитория APT видит несколько определений с разными параметрами Signed-By. Чаще всего это происходит, когда один источник задан в .list, второй в .sources, а третий остался в основном /etc/apt/sources.list.
Иногда сообщение выглядит чуть иначе: подпись недействительна, ключ не найден, файл Release не подписан. Это соседние симптомы, но очень часто их корень тот же — некорректная миграция ключей из trusted.gpg и trusted.gpg.d в отдельные keyring-файлы.
Если кратко:
NO_PUBKEY— это обычно отсутствие корректного доверенного ключа для репозитория, аSigned-By conflict— конфликт нескольких описаний одного и того же источника пакетов.
С чего начать диагностику
Первое действие — запустить обновление индекса и внимательно посмотреть, какой именно репозиторий вызывает ошибку. Не ограничивайтесь строкой с текстом про ключ: полезны URI репозитория, дистрибутив, компонент и путь к файлу, если APT его показывает.
sudo apt update
Дальше соберите все описания источников, особенно если сервером раньше занимались несколько администраторов или автоматизация разных эпох. Ищем упоминания проблемного домена во всех типовых местах.
grep -RinE "vendor.example|repo.example" /etc/apt/sources.list /etc/apt/sources.list.d/ /etc/apt/
Если точный домен ещё неясен, просто посмотрите список файлов источников:
find /etc/apt -maxdepth 2 -type f -name "*.list"
find /etc/apt -maxdepth 2 -type f -name "*.sources"
Здесь важно различать форматы. Классический вариант — строки вида deb [signed-by=/path/to/keyring.gpg] ... в файлах .list. Новый формат deb822 — это файлы .sources с полями Types, URIs, Suites, Components, Signed-By.
Именно на стыке этих форматов часто и рождаются конфликты: старый .list забыли удалить, новый .sources уже добавили, а APT видит два описания одного набора пакетов.
Если в конфигурации источников давно не наводили порядок, полезно сначала сделать резервную копию файлов из /etc/apt и только потом править их. Это особенно важно на продакшн-хостах, где ошибка в одном репозитории может остановить не только обновления безопасности, но и автоматическую установку зависимостей при деплое.

Где APT хранит ключи и почему старые схемы создают путаницу
Исторически ключи часто попадали в общий файл /etc/apt/trusted.gpg или отдельные файлы внутри /etc/apt/trusted.gpg.d/. Проблема такого подхода в том, что ключ становился глобально доверенным для APT.
С точки зрения прозрачности и принципа минимального доверия это неудобно. Через год уже трудно понять, какой ключ нужен какому репозиторию и можно ли его безопасно удалить.
Современная практика выглядит так:
- ключ конкретного репозитория хранится отдельным файлом, например в
/etc/apt/keyrings/или/usr/share/keyrings/; - источник пакетов явно указывает этот файл через
Signed-By; - старые записи из
trusted.gpgиtrusted.gpg.dпостепенно убираются, чтобы не создавать двусмысленность.
На Debian и Ubuntu обычно используют /etc/apt/keyrings/ для ключей, которыми управляет администратор, и /usr/share/keyrings/ для ключей, поставляемых пакетами. На практике важнее единообразие: один репозиторий, один файл ключа, одно описание источника.
Как безопасно исправить NO_PUBKEY
Когда вы видите NO_PUBKEY, задача состоит не в том, чтобы импортировать ключ куда угодно, а в том, чтобы привязать корректный ключ именно к нужному репозиторию. Сначала зафиксируйте ID ключа из сообщения APT и найдите файл источника, который к нему относится.
Затем проверьте, нет ли у источника уже указанного параметра Signed-By. Если он есть, но путь ведёт в несуществующий файл или в файл с неправильным содержимым, причина уже найдена.
Создайте каталог для локальных keyring-файлов, если его ещё нет:
sudo install -d -m 0755 /etc/apt/keyrings
Дальше нужен ключ поставщика репозитория. Брать его следует только из официальной документации вендора и обязательно сверять fingerprint. Общий безопасный шаблон выглядит так:
gpg --show-keys --fingerprint ./vendor-key.asc
sudo gpg --dearmor -o /etc/apt/keyrings/vendor-archive-keyring.gpg ./vendor-key.asc
sudo chmod 0644 /etc/apt/keyrings/vendor-archive-keyring.gpg
После этого поправьте описание репозитория. Для классического .list запись обычно выглядит примерно так:
deb [signed-by=/etc/apt/keyrings/vendor-archive-keyring.gpg] repo.example stable main
Для формата deb822 — так:
Types: deb
URIs: repo.example
Suites: stable
Components: main
Signed-By: /etc/apt/keyrings/vendor-archive-keyring.gpg
Путь к keyring должен совпадать буквально. Даже если у вас один и тот же ключ лежит в двух местах, оставлять двойную схему не стоит: это почти гарантированный источник будущей путаницы.
После правки проверьте результат:
sudo apt update
Если ошибка не исчезла, обычно осталось одно из трёх: ключ не соответствует подписи репозитория, в системе есть второе описание того же источника или вы редактировали не тот файл.
Как исправить Conflicting values set for option Signed-By
Эта ошибка почти всегда означает дубли. Частый сценарий: старый файл vendor.list содержит строку без signed-by или со старым путём, а новый vendor.sources уже использует другой keyring.
Найдите все совпадения по домену репозитория:
grep -Rin "repo.example" /etc/apt/sources.list /etc/apt/sources.list.d/
Теперь сравните найденные записи. Вас интересуют:
- одинаковые
URIsили один и тот же домен; - одинаковые
SuitesиComponents; - разные пути в
Signed-By; - одновременное наличие
.listи.sourcesдля одного поставщика.
Правильное решение — оставить только один актуальный файл источника. Не нужно вручную поддерживать два параллельных описания одного репозитория. Если вендор уже перешёл на deb822, обычно лучше оставить именно .sources, а старый .list убрать.
sudo rm /etc/apt/sources.list.d/vendor.list
sudo apt update
Если удалять страшно, сначала можно просто временно отключить файл, переименовав его:
sudo mv /etc/apt/sources.list.d/vendor.list /etc/apt/sources.list.d/vendor.list.disabled
sudo apt update
Если после этого конфликт пропал, причина подтверждена. Дальше уже можно окончательно удалить старый файл или привести конфигурацию к одному-единственному описанию источника.
Похожая логика полезна и в других задачах с инфраструктурой пакетов. Например, если вы дополнительно ускоряете загрузку через локальный кэш, загляните в материал про настройку Squid для APT и других пакетных менеджеров: там тоже критично избегать неявной магии и дублей.
Что делать с trusted.gpg и trusted.gpg.d
Отдельный источник путаницы — старые ключи, импортированные через apt-key. Они могут годами лежать в /etc/apt/trusted.gpg или /etc/apt/trusted.gpg.d/ и формально существовать в системе, но не решать проблему, если конкретный репозиторий настроен через Signed-By.
Сначала полезно посмотреть, какие ключи APT считает доверенными глобально:
gpg --no-default-keyring --keyring /etc/apt/trusted.gpg --list-keys
find /etc/apt/trusted.gpg.d -type f -name "*.gpg"
find /etc/apt/trusted.gpg.d -type f -name "*.asc"
Если нужный ключ найден только в глобальном хранилище, а репозиторий уже использует Signed-By, этого недостаточно. Нужно поместить ключ в отдельный keyring и явно прописать его в файле источника.
Удалять старые ключи из глобального хранилища стоит аккуратно и только после проверки, что ни один другой репозиторий на них больше не опирается. Иначе можно случайно сломать соседний источник пакетов.
Хороший рабочий порядок такой: сначала привести проблемный репозиторий к отдельному Signed-By, убедиться, что apt update проходит чисто, и только потом заниматься гигиеной старых ключей.

Переход на deb822 без новых конфликтов
Формат deb822 удобнее для сопровождения: он лучше читается, проще для автоматизации и меньше провоцирует ошибки в длинных строках. Но при миграции есть важное правило: нельзя просто добавить новый .sources рядом со старым .list и надеяться, что APT сам во всём разберётся.
Безопасная последовательность такая:
- найти старый файл
.listи сохранить его копию; - создать новый
.sourcesс корректным полемSigned-By; - отключить старый
.list; - выполнить
apt update; - только после успешной проверки удалить старый файл окончательно.
Пример минимального файла в формате deb822:
Types: deb
URIs: repo.example
Suites: stable
Components: main
Signed-By: /etc/apt/keyrings/vendor-archive-keyring.gpg
Если репозиторий поддерживает несколько компонентов или архитектур, добавляйте их явно. Чем прозрачнее файл, тем проще потом понять, откуда взялся конфликт.
Типовые ошибки при исправлении
Даже опытные админы регулярно наступают на одни и те же грабли:
- скачали новый ключ, но забыли поменять путь
Signed-Byв источнике; - создали
keyringв/etc/apt/keyrings/, но параллельно оставили старый.listбез этого параметра; - взяли ключ другого репозитория того же вендора;
- не проверили fingerprint и импортировали устаревший или чужой ключ;
- исправили запись в одном файле, но забыли про дубликат в другом;
- смешали разные форматы описания источников и получили новый
Signed-By conflict.
Ещё одна неприятная ловушка — автоматические установочные скрипты. Некоторые продукты при обновлении снова создают свой .list рядом с вашим вручную исправленным .sources. Если проблема повторяется после обновления пакета, проверьте, не генерирует ли пакет файл источника заново.
Быстрый чек-лист для продакшн-сервера
Если нужно исправить проблему быстро и без лишнего риска, придерживайтесь такого порядка:
- сделайте копию текущих файлов
/etc/apt/sources.listи/etc/apt/sources.list.d/; - запустите
apt updateи выпишите проблемный репозиторий и ID ключа; - найдите все описания этого репозитория в
.listи.sources; - оставьте только один файл источника;
- создайте отдельный
keyringдля этого репозитория; - укажите единый путь в
Signed-By; - проверьте fingerprint ключа;
- повторите
apt update; - только после успеха разбирайте старые ключи в
trusted.gpg.d.
На серверах с конфигурационным менеджментом полезно сразу зафиксировать состояние в Ansible, Salt или другой системе управления, чтобы ручная правка не потерялась при следующем прогоне.
Как понять, что проблема решена правильно
Хороший результат — это не просто отсутствие ошибки в текущий момент. Правильно исправленная конфигурация имеет несколько признаков: для каждого стороннего репозитория есть один явный файл источника, для него существует отдельный понятный keyring, путь в Signed-By совпадает с фактическим местом хранения ключа, а в системе нет дублей на один и тот же источник пакетов.
Если после исправления apt update проходит чисто, а список файлов в /etc/apt/sources.list.d/ выглядит предсказуемо и без мусора, значит вы не просто погасили симптом, а действительно навели порядок.
Именно такой подход окупается на длинной дистанции. Репозитории сторонних вендоров меняют ключи, переходят на новые форматы и обновляют инструкции. Когда всё разложено по отдельным keyring-файлам и источники описаны без дублей, любые будущие изменения становятся заметно проще и безопаснее.


