Сообщение RTNETLINK answers: File exists в Debian и Ubuntu сбивает с толку даже опытных администраторов. Формулировка выглядит так, будто проблема связана с каким-то файлом, но на практике речь почти всегда не о файловой системе. Ядро Linux через интерфейс netlink сообщает, что объект уже существует.
Чаще всего это IP-адрес, маршрут, правило маршрутизации или другой сетевой объект, который вы пытаетесь добавить повторно. Внешне сценарии похожи: не проходит ip addr add, падает ip route add, ругается netplan apply или в журнале systemd-networkd видно, что маршрут уже существует.
Хорошая новость в том, что ошибка обычно диагностируется быстро. Если не гадать, а последовательно проверить текущее состояние интерфейсов, адресов, таблиц маршрутизации и конфигурации, источник дубликата находится без особой магии.
Главный принцип здесь простой: команды add в iproute2 создают новый объект. Если он уже есть, вы получаете File exists. Если же вам нужно не «добавить», а «обеспечить нужное состояние», чаще подходят replace, предварительное удаление старой записи или исправление постоянного конфига.
На удалённом сервере такие ошибки особенно неприятны: неверная правка netplan или systemd-networkd может закончиться потерей SSH-доступа. Поэтому любые изменения сети лучше вносить с планом отката: иметь вторую сессию, сохранённый вывод текущих настроек и доступ к консоли провайдера.
Что на самом деле означает RTNETLINK answers: File exists
Утилита ip не редактирует конфигурационные файлы напрямую. Она отправляет запрос ядру через netlink: назначить адрес, создать маршрут, добавить правило. Если объект с такими ключевыми параметрами уже существует, ядро возвращает ошибку существования, а утилита печатает RTNETLINK answers: File exists.
Важно, что «уже существует» не всегда означает полное текстовое совпадение команды. Например, маршрут в ту же сеть через тот же шлюз и в той же таблице может считаться тем же самым объектом, даже если вы добавляете его из другого скрипта. То же самое с адресами: повторное назначение 192.0.2.10/24 на тот же интерфейс завершится той же ошибкой.
Если коротко: проблема обычно не в netlink и не в «битой сети», а в попытке повторно создать уже существующий сетевой объект.
Практический вывод простой: сначала смотрим, что уже есть в системе, и только потом меняем команды или конфиги. Очень часто объект создался раньше другим слоем: DHCP, cloud-init, netplan, networkd, ifupdown или вашим automation.
Где ошибка встречается чаще всего
Повторный ip addr add
Самый простой случай: адрес уже назначен интерфейсу, а скрипт запускается повторно. Это типичная история для самописных provisioning-скриптов, unit-файлов systemd и старой инициализации через rc.local.
ip addr add 192.0.2.10/24 dev eth0
Если адрес уже есть на интерфейсе, команда вернёт ошибку.
Повторный ip route add
Второй частый сценарий — статический маршрут уже присутствует в таблице маршрутизации. Например, вы добавили его вручную, а затем тот же маршрут пришёл из конфигурации networkd, netplan или по DHCP.
ip route add 10.10.0.0/16 via 192.0.2.1 dev eth0
Если такой маршрут уже существует в таблице main или в нужной вам таблице policy routing, получите ту же ошибку.
Дубликаты в systemd-networkd
При использовании systemd-networkd проблема часто видна в журнале. Обычно она возникает, когда маршрут одновременно описан в секции [Route] и приходит по DHCP, RA или из другого .network-файла, который тоже совпал по интерфейсу.
Дубликаты в netplan
Для Ubuntu типична ситуация, когда в /etc/netplan/ лежит несколько YAML-файлов, и вместе они генерируют одинаковые адреса или маршруты. Такое часто встречается после ручной миграции, изменений cloud-init или правок шаблонов образа.
Отдельная ловушка — сочетание routes:, gateway4, DHCP и автоматически созданных файлов. Итог обычно один: дублирующийся маршрут и ошибка при применении конфигурации.

Базовая диагностика: что проверить в первую очередь
Прежде чем что-либо исправлять, соберите факты. Одной команды мало: нужно увидеть интерфейсы, адреса, маршруты, правила policy routing и журнал той службы, которая управляет сетью.
ip -br link
ip -br addr
ip route show table main
ip route show table all
ip rule show
networkctl status --all
journalctl -u systemd-networkd -b --no-pager
netplan get
Если система не использует systemd-networkd, часть команд будет неактуальна, но такой набор даёт хороший старт. На Ubuntu отдельно полезно проверить, кто именно рендерит конфигурацию netplan.
ls -l /etc/netplan
grep -R "renderer:" /etc/netplan
systemctl is-active systemd-networkd
systemctl is-active NetworkManager
После этого ответьте на три вопроса:
- Какой объект уже существует: адрес, маршрут или правило.
- Кто его создал: вручную, DHCP, netplan, networkd, cloud-init или старый скрипт.
- Нужно ли вам заменить запись, удалить её или убрать дубликат из конфигурации.
Если сервер развёрнут из шаблона или golden image, отдельно проверьте, не осталось ли автоматической генерации сети. Это частая причина повторного появления маршрутов после ребута. По теме полезно почитать про подготовку образов с cloud-init без сетевых сюрпризов.
Как исправить ip addr add file exists
Если ошибка возникает на разовой команде, сначала проверьте, назначен ли адрес интерфейсу.
ip addr show dev eth0
Если адрес уже есть, это не всегда авария. Возможно, ваш скрипт просто неидемпотентен и запускается повторно. Тогда лечить нужно не симптом, а логику.
Вариант 1. Использовать replace
Если вам нужно гарантировать наличие адреса, а не обязательно создать его с нуля, удобнее применять replace.
ip addr replace 192.0.2.10/24 dev eth0
Для automation это обычно безопаснее, чем голый add.
Вариант 2. Удалить и добавить заново
Подходит, если вы точно понимаете последствия и не рискуете отрезать себе доступ к серверу.
ip addr del 192.0.2.10/24 dev eth0
ip addr add 192.0.2.10/24 dev eth0
Если это основной адрес для SSH, такой способ на удалённой машине может быть опасен.
Вариант 3. Сделать проверку в скрипте
Если команда вызывается из shell-скрипта, лучше сперва проверить наличие адреса.
ip -4 addr show dev eth0 | grep -q '192.0.2.10/24' || ip addr add 192.0.2.10/24 dev eth0
Это особенно полезно для старых bootstrap- и deploy-скриптов.
Как исправить ip route add file exists
С маршрутами всё чуть сложнее, потому что дубли бывают не только буквальными, но и логическими. Вы можете не видеть в выводе «точно такую же» строку, но маршрут уже существует с тем же назначением и таблицей.
Сначала проверьте таблицы маршрутизации:
ip route show table main
ip route show table all
Если используется policy routing, обязательно смотрите и правила:
ip rule show
Когда помогает replace
ip route replace 10.10.0.0/16 via 192.0.2.1 dev eth0
Это лучший вариант для скриптов, которым нужно добиться заданного состояния без падения на повторном запуске.
Когда нужно удалить старую запись
Если маршрут уже существует, но с неверным шлюзом, интерфейсом, метрикой или таблицей, лучше удалить его явно и создать заново.
ip route del 10.10.0.0/16 via 192.0.2.254 dev eth0
ip route add 10.10.0.0/16 via 192.0.2.1 dev eth0
Иногда важно явно указать таблицу:
ip route show table 100
ip route add 10.10.0.0/16 via 192.0.2.1 dev eth0 table 100
Когда дубликат создаёт DHCP
Очень частый случай в Debian и Ubuntu: вы прописываете статический маршрут или default route, а DHCP уже прислал ту же запись. Тогда нужно устранять не симптом, а источник: либо не добавлять маршрут вручную, либо отключать его получение динамически.
Если у вас в сети задействован IPv6, полезно также помнить про RA и DHCPv6: маршрут может приходить не только по IPv4 DHCP. По теме пригодится разбор маршрутизации IPv6 через SLAAC и DHCPv6.
Проблемы в netplan: duplicate route и конфликт настроек
В Ubuntu netplan часто становится источником дубликатов после ручных правок в нескольких файлах. Netplan объединяет YAML из /etc/netplan/, и итоговая конфигурация может содержать повторяющиеся адреса и маршруты.
Сначала посмотрите итоговое дерево настроек:
netplan get
Затем проверьте все YAML-файлы:
ls -1 /etc/netplan
sed -n '1,200p' /etc/netplan/*.yaml
Особенно внимательно проверьте такие сочетания:
- одинаковые маршруты в разных файлах;
gateway4и тот же default route вroutes:;- DHCP плюс вручную заданный default route;
- cloud-init создал один файл, а вы добавили второй вручную;
- один и тот же интерфейс описан сразу в нескольких местах.
Практически безопасный путь — собрать настройки интерфейса в одном месте, убрать дубликаты и применять изменения через проверку.
netplan generate
netplan try
На удалённом сервере netplan try особенно полезен: если сеть сломается, конфигурация откатится автоматически. И только после успешной проверки уже имеет смысл применять изменения постоянно.
netplan apply
Если проблема связана с cloud-init, иногда правильнее не править следствие, а привести в порядок сам шаблон или отключить автоматическое сетевое управление там, где оно больше не нужно.
Проблемы в systemd-networkd: route already exists
У systemd-networkd ошибка чаще всего всплывает в журналах как результат конфликта между несколькими источниками конфигурации. Например, один .network-файл задаёт маршрут вручную, а DHCP на том же интерфейсе приносит такой же.
Посмотреть статус и журнал можно так:
networkctl status eth0
journalctl -u systemd-networkd -b --no-pager
Дальше проверьте содержимое файлов:
find /etc/systemd/network -maxdepth 1 -type f | sort
sed -n '1,200p' /etc/systemd/network/*.network
sed -n '1,200p' /etc/systemd/network/*.netdev
sed -n '1,200p' /etc/systemd/network/*.link
Что искать в первую очередь:
- дублирующиеся секции
[Route]; - одинаковые совпадения
[Match]для одного интерфейса; - включённый DHCP и одновременно статически заданный default route;
- маршруты, приходящие по RA или DHCPv6 и дублируемые вручную;
- старые файлы, оставшиеся после миграции.
После исправления конфигурации полезно сначала перечитать настройки, а затем уже применять изменения.
networkctl reload
systemctl restart systemd-networkd

Статический маршрут в Debian и Ubuntu: как прописать без конфликтов
Когда вам нужен постоянный статический маршрут, главное — выбрать один источник истины. Не стоит одновременно управлять одним и тем же маршрутом через netplan, networkd, ifupdown и отдельный shell-скрипт.
Нормальная стратегия выглядит так:
- Определите, кто управляет сетью на сервере: netplan, systemd-networkd, ifupdown, NetworkManager или cloud-init.
- Уберите лишние источники, которые тоже назначают адреса и маршруты.
- Оставьте маршрут только в одном месте.
- Проверьте, не приходит ли он динамически по DHCP или RA.
- После применения конфигурации перепроверьте таблицы маршрутизации и доступность сервера.
Для серверной Ubuntu чаще всего логично держать всё в netplan. Для чистого Debian с networkd — в .network-файлах. Для старых систем с ifupdown — не дублировать маршруты во внешних post-up-скриптах без необходимости.
Частые причины, о которых забывают
Cloud-init перезаписывает сеть
На облачных серверах и VPS это классика. Вы исправляете netplan вручную, всё работает, но после перезагрузки маршрут снова появляется. Причина в том, что cloud-init заново генерирует сетевые настройки.
Маршрут находится в другой таблице
Администратор смотрит только ip route, не видит конфликта и удивляется ошибке. Но запись находится не в main, а в отдельной таблице, на которую ссылаются правила ip rule.
Несколько адресов на одном интерфейсе
При secondary IP, VRF, policy routing и смешанной IPv4/IPv6-конфигурации легко принять нормальное состояние за ошибку или наоборот. Поэтому смотрите полную картину, а не один фрагмент вывода.
Скрипт запускается больше одного раза
После миграции на systemd старая логика может остаться одновременно в cron, rc.local, unit-файле и cloud-init. В итоге одна и та же команда выполняется несколько раз.
Безопасный порядок действий на удалённом сервере
Если правите сеть по SSH, действуйте осторожно. Ошибка File exists сама по себе не так опасна, как попытка быстро «починить» её в лоб и потерять доступ к серверу.
- Откройте вторую SSH-сессию и не закрывайте первую.
- Сохраните текущий вывод
ip addr,ip routeи конфиги сети. - Проверьте, кто реально управляет сетью.
- Вносите изменения только в один источник конфигурации.
- Для Ubuntu используйте
netplan tryпередnetplan apply. - Для критичных машин заранее убедитесь, что доступна консоль провайдера.
На практике такие задачи удобно сначала обкатывать на отдельном VDS, а затем переносить проверенную конфигурацию в production. Это заметно снижает риск сюрпризов во время сетевых изменений.
Мини-чеклист: как быстро найти источник ошибки
- Посмотрите, что уже существует:
ip -br addr,ip route show table all,ip rule show. - Определите управляющий слой: netplan, networkd, ifupdown, DHCP или cloud-init.
- Найдите дубликат в конфиге или среди динамически полученных маршрутов.
- Для разовой команды используйте
replaceвместоadd, если это уместно. - Для постоянной настройки уберите дубль из единственного источника конфигурации.
- После изменений перепроверьте состояние и журнал.
Итог
Ошибка RTNETLINK answers: File exists почти всегда означает одно: адрес, маршрут или правило уже есть, а система пытается добавить их повторно. Для ip addr add виноват обычно уже назначенный IP или повторный запуск скрипта. Для ip route add типичны дубли маршрутов, конфликт с DHCP, policy routing или несколько источников конфигурации.
Самый надёжный подход — не лечить симптом точечной командой, а привести сеть к одному источнику истины. Тогда конфигурация становится предсказуемой, автоматизация — идемпотентной, а перезагрузки и перезапуски сетевых служб перестают приносить неприятные сюрпризы.


