What “Unmarshal” Means in Clash Meta
Clash Meta and other mihomo-based cores read your profile as structured data. Internally the runtime parses the text of config.yaml into Go structs. When something in that pipeline fails, logs and GUI surfaces often say unmarshal or yaml together with a fragment of the error. That is not a mysterious networking fault at the IP layer; it almost always means the file is not valid YAML for the schema the core expects, or a value landed in the wrong shape (for example a scalar where a list should be). Treat the message as a pointer to a line or a key, not as a reason to reinstall the whole client.
The distinction matters because many users first learned configs from JSON or from editors that auto-format loosely. YAML looks forgiving until you mix tabs with spaces, paste a second rules: block under the first, or let a visual editor “helpfully” reflow list items. The core does not guess intent; it either accepts the tree or stops before binding listeners. Your job is to make the tree unambiguous again.
Read the Error Before You Edit Blindly
Start by copying the full error string from the client log or toast. Good parsers report a line and column, a key path, or at least a substring near the failure. Open the same file your client loads—sometimes that is not the buffer you see in a web converter—and jump to that line in an editor that shows whitespace. If the GUI hides details, export the profile to disk and open it in VS Code, Neovim, or any editor with YAML awareness; avoid rich-text tools that strip spaces.
When the message mentions duplicate key or mapping key already defined, resist the urge to tweak random proxies. Search the document for repeated top-level declarations such as proxy-groups:, rules:, proxies:, or dns:. Those duplicates are among the fastest ways to turn a working file into one that will not start, because the human eye often skims past the second block if both look “reasonable” at a glance.
Indentation: Spaces, Lists, and Nesting
YAML uses indentation to express hierarchy. Clash profiles are mostly mappings and sequences: proxy-groups is a sequence of mappings; each group has name, type, and proxies as a sequence of strings. A single misplaced space can move a key inside the previous item instead of beside it, which produces either a parse error or—worse—a structure the unmarshaler cannot map onto the config structs.
Follow these habits: use spaces only, pick one indent width (two spaces is common in Clash examples), and never mix tabs. Align list dashes consistently: each - name: Example under proxies: should share the same depth. When you append a new rule at the bottom of rules:, match the dash column used by the lines above. If you paste from a website that used four-space indents into a file that used two, reconcile the block as a whole instead of “fixing” line by line.
Watch for editors that auto-indent rules entries as if they were YAML keys under a mapping. A valid rule line is usually a list item beginning with - MATCH,... or - DOMAIN-SUFFIX,..., not a bare string without the leading dash at the correct level. Conversely, accidental extra dashes can create nested lists the parser reads as empty or malformed entries.
Duplicate Keys at the Top Level
In YAML, a mapping should not repeat the same key at the same level. Yet merged configs frequently contain two proxy-groups: sections because someone appended a template that already included groups, or a subscription converter emitted a full profile that was concatenated to an existing one. The same happens with rules: when users paste a “minimal ruleset” below an existing list without deleting the old block.
The fix is structural: merge by intent, not by concatenation. Keep one proxies: list (or rely on proxy-providers), one proxy-groups: section, and one rules: section. Move any extra nodes into the single list, move group definitions into the single groups section, and interleave or reorder rules inside the single rules: array according to precedence. For a refresher on how rule order interacts with strategy groups once the file parses, see our deep dive on rule-based splitting.
Some GUIs hide the duplication by showing tabs per section while the underlying file still contains repeated keys. When in doubt, search in raw text. A quick pattern is counting occurrences of ^proxy-groups: or ^rules: at column one in a regex-aware editor; more than one hit at the document root is a red flag.
Merge Artifacts From Subscriptions and Converters
Remote subscriptions often ship either a Base64 node list or a YAML fragment. Converters may output a full profile when you only needed proxies. Pasting that output beneath your hand-tuned skeleton duplicates not only proxies: but sometimes entire dns: or tun: blocks. Even when duplication is legal in a sloppy human sense, the Clash schema expects single authoritative sections for many keys.
If you combine a local skeleton with a converted blob, prefer proxy-providers or explicit proxies imports over pasting the remote file inline unless you truly intend to inline everything. Our subscription management guide walks through how remote bodies differ from full profiles and why separating node refresh from policy keeps rollbacks simpler—fewer moving parts also means fewer chances to duplicate a top-level key during a midnight edit.
Anchors, Aliases, and Advanced YAML
Power users sometimes introduce YAML anchors (&) and aliases (*) to deduplicate snippets. Not every toolchain in the Clash ecosystem round-trips those features cleanly; a GUI may expand or collapse them on save. If unmarshal errors appear immediately after such an edit, simplify: remove anchors, expand to plain repeated blocks temporarily, and confirm the core starts. You can reintroduce clever structure once the baseline file is accepted.
Similarly, be cautious with literal block scalars and folded strings for multiline TLS certificates or keys. A misplaced indentation on a certificate line can terminate the literal early and leave the rest of the file parsed as unexpected keys. Keep PEM blobs in dedicated files referenced by certificate paths when possible, which also keeps secrets out of quick-share screenshots.
Validate Offline Before You Relaunch
When the profile is large, use external validation to avoid a restart loop. Command-line YAML linters and schema-aware tools can catch duplicate keys even if your editor does not. Running a small script or yq to dump the parsed tree will fail fast on the same lines the core would reject. If you prefer a GUI workflow, split the file: comment out half the rules temporarily (using YAML comments with #, not by mangling dashes), reload, and bisect until the offending region is obvious.
Always keep a known-good backup on disk—timestamped—before bulk pastes. Version control helps, but even a duplicate file named config.working.yaml saves hours when you need to diff against a broken variant. Binary search on sections (proxies versus rules versus dns) narrows failures in minutes compared with random tweaks.
When YAML Is Valid but the Core Still Complains
Rarely, the file parses as YAML yet fails unmarshaling into Clash structs because a field has the wrong type: a string where an integer is required, a missing required key inside a group, or an enum value the core does not recognize. Those errors sometimes still say unmarshal but reference a field name such as proxy-groups[3].type. Cross-check the field against upstream documentation for your exact mihomo version; a key renamed between releases looks like a syntax problem even though the YAML is technically well formed.
Upgrading the core without reading release notes is a common trigger: new defaults appear, deprecated keys warn, and occasionally strictness increases. If indentation and duplicates are clean, read the versioned docs and compare your profile to a minimal official example. The documentation hub links feature overviews that complement blog walkthroughs when you need authoritative field names.
Mental Model: One Tree, One Source of Truth
Think of your profile as a single tree. Each branch—port, dns, proxies, proxy-groups, rules—should appear once at the layer where the schema expects it. Visual editors that show cards per section can obscure that unity, which is why raw-text review remains valuable. When collaborators share snippets, merge them into the correct branch instead of stacking full trees beneath one another.
This mindset also helps when you troubleshoot policy versus syntax. If the client starts but traffic misbehaves, you are in rule-order land. If the client never binds ports, you are still in parse land. Keeping the two phases separate prevents thrashing between DNS tweaks and YAML fixes that do not belong together.
Recovery Checklist
In short: capture the error text and line, show invisible characters, eliminate duplicate top-level keys, normalize indentation with spaces, validate with an external tool or bisection, and restore from backup if needed. Reintroduce changes in small commits to your personal config history. Once the core loads, exercise a simple MATCH rule and a known proxy to prove the pipeline end-to-end before layering optional features again.
Syntax-level failures are frustrating because they block everything else, yet they are usually deterministic. Patience and systematic search beat repeatedly clicking “restart” without diffing the file. Compared with opaque network outages, a YAML error gives you a breadcrumb—use it.
Wrap-up
Fixing Clash Meta YAML unmarshal issues is less about secret keywords and more about respecting the format: consistent indentation, no duplicate keys for major sections, and careful merges when subscriptions or converters hand you a full profile disguised as a snippet. Once the tree loads, you can return to tuning split logic and DNS with confidence.
→ Download Clash for free and experience the difference on the platform you use daily, then keep a clean baseline profile and iterate in small, verifiable steps.