«configuration is invalid» в sing-box: как понять причину и починить
Обновлено 2026-07-03
Коротко: sing-box отвергает конфиг целиком и пишет причину сразу после двоеточия — читать нужно именно этот кусок, там указан путь до проблемного поля. Пять самых частых поводов: битый JSON (лишняя запятая), отсутствующий default_domain_resolver (обязателен с 1.12), rule_set типа local ссылается на несуществующий .srs, поле переименовали при обновлении версии, два outbound с одинаковым tag. Проверять до запуска: sing-box check -c config.json.
Ошибка выглядит пугающе, но она из добрых: sing-box не запускается наполовину, а отказывается целиком и говорит, что именно ему не понравилось. Проблема только в том, что сообщение длинное и главное в нём — не первые слова, а то, что идёт после двоеточия.
Сначала прочитайте саму ошибку
Полное сообщение выглядит так: FATAL[0000] configuration is invalid: parse config: ... — и вот этот хвост после двоеточия и есть ответ. sing-box указывает путь до поля в JSON: например route.rules[3] или outbounds[1].tls. Считать индексы удобно, открыв конфиг в редакторе со сворачиванием блоков. Отдельно полезная команда: sing-box check -c config.json — она проверяет конфиг, ничего не запуская, и печатает ту же ошибку.
Причина 1: битый JSON
Самое частое и самое обидное — лишняя запятая перед закрывающей скобкой, незакрытая кавычка, комментарий в стиле // (в JSON их нет). Такой конфиг не доходит даже до проверки смысла. Признак: в ошибке будет упомянут символ или строка, а не имя поля. Лечится любым JSON-валидатором или тем же sing-box check.
Причина 2: нет default_domain_resolver (с версии 1.12)
Начиная с sing-box 1.12 в секции route обязателен default_domain_resolver — резолвер, который используется, когда домен нужно разрешить в момент установки соединения. Раньше это работало по умолчанию, теперь без явного указания конфиг отвергается. Добавьте в route: "default_domain_resolver": { "server": "remote" }, где remote — тег вашего DNS-сервера из секции dns. Это самая частая причина, по которой конфиг, работавший год назад, вдруг перестал запускаться после обновления.
Причина 3: rule_set ссылается на файл, которого нет
Если у вас { "type": "local", "path": "...srs" }, а файла по этому пути нет — отвергается весь конфиг, а не одно правило. Поэтому опасно ссылаться на .srs, который скачивается отдельно: не скачался — и тоннеля нет вообще. Надёжнее либо класть .srs рядом и проверять наличие перед запуском, либо продублировать логику обычным правилом domain_suffix, чтобы при пропаже rule_set маршрутизация деградировала, а не умирала.
Причина 4: поле переименовали при обновлении
sing-box меняет схему между минорными версиями чаще, чем хотелось бы. Классика: в правилах маршрутизации outbound в ряде случаев уступил место action, устаревшие формы записи DNS-серверов перестали приниматься. Если конфиг взят из статьи годичной давности, а бинарник свежий — сверьтесь с официальной документацией именно вашей версии: sing-box version покажет её.
Причина 5: дубли тегов
Два outbound с одинаковым tag — и конфиг невалиден. Легко получить, когда вручную склеиваешь ноды из нескольких подписок: имена совпадают. Ошибка укажет на дублирующийся тег.
Если разбираться не хочется
Всё вышеперечисленное — плата за ручную сборку конфига. Клиенты, которые собирают конфигурацию сами и обновляют её на лету, эту категорию проблем снимают: Orden построен на том же ядре sing-box (VLESS-Reality + Hysteria2 с автопереключением), конфиг генерируется под вашу версию, руками править нечего. Код открыт: github.com/tsyrenov1987/orden-android-client. Рабочий пример конфига с разбором граблей выложен отдельно: https://github.com/tsyrenov1987/orden-singbox-configs
Orden — VPN, который сам обновляется и переживает DPI
VLESS-Reality + Hysteria2, автопереключение, банки и Госуслуги работают напрямую. На устройстве, без логов, открытый код.
Открыть Orden →