现象:unmarshal 报错与配置无法启动

使用 Clash Meta(现多称为 mihomo 内核)时,若 config.yaml(或图形界面生成的等价文本)存在语法问题,内核在读取配置阶段就会失败。界面常见提示包括「YAML 解析失败」「unmarshal 错误」「无法启动」「配置无效」等,日志里往往带有 行号字段路径。这与节点失效、规则不匹配等业务问题不同:在解析通过之前,代理根本不会进入运行态,因此所有功能都会停摆。

高频原因可以归为三类:缩进与层级错乱(含 Tab 与空格混用)、同一文档内重复出现顶层的 proxiesproxy-groupsrules 等键,以及从订阅或网页复制时带入的不可见字符、错误编码。下面按排查顺序说明如何处理;若你更关心订阅与片段格式本身,可先对照 订阅管理实践,再回到本文处理「合成后的整文件」语法。

第一步:锁定报错行与字段语义

请优先打开内核或客户端的原始日志,而不是只看弹窗摘要。多数实现会给出类似「line 123」「column 5」或「yaml: unmarshal errors … mapping key … already set」的信息。行号以当前保存的文本为准:若编辑器自动换行显示与真实换行不一致,请以导出后的纯文本为准(必要时用「在终端中显示行号」的方式核对)。

若提示某键「already set」「duplicate key」,说明同一层级下同名键出现了两次。在 YAML 中,顶层的 proxies:proxy-groups:rules:dns:tun: 等各自只能出现一次;重复往往不是「多写了几条规则」,而是整段键名又写了一遍。这与后面在 rules: 列表里写多行 - RULE 完全不同,后者是合法的列表项追加。

建议:每次大改前复制一份带时间戳的备份文件。语法错误往往发生在「合并两段网上下载的模板」时,有备份可以秒级回滚,再逐段对比差异。

第二步:修正缩进与列表层级

YAML 用缩进表达嵌套。Clash 系配置习惯使用两个空格作为一级缩进;不要使用 Tab 与空格混排,否则表面看起来对齐,解析器却可能在某一行误判层级,报「did not find expected key」或指向完全不相干的行号。

典型错误包括:把 - name: … 下列表项的子字段少缩进了一格,导致上一条代理条目未正确结束;从浏览器复制规则时,行首意外多了或少了空格;在 proxy-groups 里嵌套 proxies: 子列表时,与顶层的 proxies: 段落混淆——请记住:全局节点定义只在顶层 proxies: 下列出,策略组里引用节点名称即可,不要再起一个新的顶层 proxies:

# Indentation example — use spaces only, 2 spaces per level
proxies:
  - name: node-a
    type: ss
    server: example.com
    port: 443
proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - node-a
      - DIRECT

若你使用 Visual Studio Code、Cursor 等编辑器,可打开「显示空白字符」或仅将缩进渲染为空格,快速发现 Tab。若规则很长,也可把报错行附近二十行单独剪到新文件做最小复现,便于对照 规则与策略组详解 中的结构说明。

第三步:查找并合并重复的顶键

重复键是最容易被忽视的致命问题。常见场景是:先有一份完整配置,又从别处粘贴了带 rules:proxy-groups: 的片段,结果文件中出现两个 rules:。解析器通常只保留后者或直接报错,取决于实现与重复位置;mihomo 侧往往会明确提示 unmarshal 失败。

处理原则:每个顶键只保留一段,把需要追加的内容并入现有段落。例如有两段 rules:,应把第二段中的 - DOMAIN-SUFFIX,… 行逐一剪切到第一段 rules: 列表末尾(并注意 MATCH 仍应在最后)。proxy-groups 同理:把缺失的策略组合并进同一个 proxy-groups: 列表,而不是再写一个新的 proxy-groups:

使用「全文搜索」功能在配置中查找第二次出现的 ^proxies:^proxy-groups:^rules:(行首匹配)。若命中两处及以上,几乎可以肯定需要人工合并。合并后再次全文搜索确认每个顶键仅出现一次,再尝试启动。

部分在线「配置生成器」会输出完整可运行文件;若你把它整段贴进已有配置,而不是只替换其中一节,极易产生重复顶键。导入时务必明确自己要替换的是「整文件」还是「某一段落」。

profile、子配置与「看不见的第二份」

某些图形客户端会把主配置与 profile、片段文件拆开存储。若你看到主文件已经干净,但启动仍报重复或解析错,请检查是否还有自动合并进来的片段(例如自定义规则片段、额外的 YAML 片段路径)。同一键在合并后的最终文本中仍只能出现一次。排查时以客户端「导出完整配置」或「合并预览」为准,而不是只看当前编辑窗口。

编码、BOM 与复制来源

配置文件应使用 UTF-8 无 BOM 保存。若从旧版 Windows 记事本或某些网页复制,可能带入 UTF-8 BOM 或全角标点;极端情况下首行之前存在不可见字符,会导致解析器从第一行就报错。可在编辑器中「另存为 UTF-8(无 BOM)」,或删除文件开头异常空白后重试。

另需注意:从聊天软件、论坛复制的代码块有时会插入智能引号、全角冒号等非 ASCII 字符,出现在键名或规则类型中时会触发奇怪错误。对 rules 一行一条的文本,建议只使用半角逗号与半角字母关键字(如 DOMAIN-SUFFIXGEOIP)。

建议校验流程与何时对照升级文档

在本地可用任意 YAML 校验器或 IDE 插件先做一次语法检查,再交给内核。若错误信息指向某个字段类型(例如某键应为字符串却写成了列表),可能是版本差异:mihomo 与旧版 Clash 的字段并不完全一致。此时应对照 Meta 升级与迁移指南,确认废弃字段已替换,避免把「版本不兼容」误判成「单纯 YAML 手误」。

当语法全部正确却仍无法启动时,再排查端口占用、权限、规则集下载失败等问题;那些阶段的报错通常不再是 unmarshal,而是运行时日志。把「解析阶段」与「运行阶段」分开,能显著缩短排错时间。

小结:先语法、后业务

Clash MetaYAML 配置一旦在缩进或重复键上出错,就会表现为 unmarshal 失败与配置无法启动。按日志行号修正空格层级、合并重复的 proxy-groupsrules 顶段、统一编码与复制来源,绝大多数启动阻塞都能当场解除。养成备份与分段合并的习惯后,这类问题也会越来越少。

相比在编辑器里反复试错,使用维护积极、内置配置校验与清晰错误提示的 Clash·mihomo 客户端,往往能把「语法错误」拦截在保存之前;与零散工具链相比,在稳定性与可读性上通常更省心。

→ 立即免费下载 Clash,开启流畅上网新体验