sing-box 升级后 DNS 配置报错:旧 address 写法怎么迁移

文章目录
旧配置一直能用,升级 sing-box 后却在 DNS 部分报错,可能不是节点失效,而是配置格式已经变了。旧的 DNS 服务器写法从 1.12 起废弃,在 1.14 被移除。这里说的是使用 address 字段的旧服务器格式,不是所有 DNS 配置都不能用了。
如果日志已经指向旧 DNS 格式或不支持的字段,应先迁移配置。反复更新机场订阅,未必会改变你自己保存的 DNS 覆写。
先判断配置由谁生成
如果是手动维护 JSON,直接修改自己的配置副本。如果是客户端或转换工具生成,先核对它是否支持当前内核的新格式;否则每次刷新订阅,旧格式还会被重新生成。
不要把原始订阅、客户端覆写和最终运行配置混为一份文件。检查报错时,找到实际加载的那一份,确认 DNS 块里是否仍然使用旧 address 写法。旧格式的移除说明和迁移说明列出了对应关系。
UDP 服务器:从地址字符串改成类型和服务器
旧写法:
{
"dns": {
"servers": [
{
"tag": "dns-example",
"address": "1.1.1.1"
}
]
}
}
只转换字段结构时,新写法如下。注意:新旧格式省略出站字段时的行为不同,下面并不保证保留原先的解析出口。
{
"dns": {
"servers": [
{
"type": "udp",
"tag": "dns-example",
"server": "1.1.1.1"
}
]
}
}
保留原来的 tag,可以减少 DNS 规则引用失效的问题。这里的地址仅用于展示字段格式,不是在建议所有网络统一使用这个 DNS,也不是一份完整代理配置。
别漏掉出站路径的变化
旧 DNS 服务器未指定 detour 时,会使用默认出站;新格式的默认拨号行为相当于直连。原来通过代理访问 DNS 上游的配置,只转换上面的字段可能就会改变解析出口。UDP 说明和 HTTPS 说明都单独列出了这个差异。
如果原本就要通过某个代理出站访问上游,应在新配置里明确保留对应出站,例如:
{
"type": "https",
"tag": "dns-https",
"server": "1.1.1.1",
"server_port": 443,
"path": "/dns-query",
"detour": "your-existing-proxy-outbound"
}
your-existing-proxy-outbound 是占位名称,必须替换为自己配置中已经存在的出站 tag。这里没有新增一个实际代理。迁移时保留原先预期的路径,而不是一律改为代理或一律直连;还要防止解析代理服务器域名时出现依赖循环。
HTTPS 服务器:不要把整条 URL 塞进 server
旧写法把协议、地址和路径放在一个字符串里:
{
"tag": "dns-https",
"address": "https://1.1.1.1/dns-query"
}
新格式将不同部分拆开:
{
"type": "https",
"tag": "dns-https",
"server": "1.1.1.1",
"server_port": 443,
"path": "/dns-query"
}
server 是服务器地址,不应带 https:// 和完整路径。端口和请求路径使用各自的字段。自建 DoH 如果不是默认端口或路径,必须保留原来的实际值,不能照抄例子后把自己的服务地址改掉。HTTPS DNS 的字段说明可以逐项核对。
这几种情况不能只换字段名
本地解析、FakeIP 和拒绝应答,在迁移文档中各有示例。尤其是旧的 rcode://refused,不能机械地改成一个名字相近的服务器字段;应按当前 DNS 规则动作的写法处理。
DNS 服务器地址如果本身是域名,还涉及用于解析该域名的解析器。配置存在 address_resolver、策略或出站依赖时,要核对完整迁移关系。只把 address 改成 server,可能仍然无法工作。
修改后先校验,再启动
在保留原文件的前提下,使用准备运行的同一版 sing-box 校验配置:
sing-box check -c config.json
校验命令的用途是检查配置能否被解析,不会证明 DNS 服务器可达,也不会证明节点可用。命令说明见配置文档。
若校验通过、启动后域名仍无法解析,再检查 DNS 上游的可达性和所用出站。若校验失败,先按第一条错误检查字段和所在层级,不要一口气更换 DNS、代理节点与路由规则。
本页的 JSON 是字段迁移示例,未在你的设备或订阅上执行。排查其他连接问题,可接着使用连接检查顺序。