Understand the message: valid YAML can still be an invalid Mihomo configuration
yaml: unmarshal errors usually means the program parsed enough YAML to begin converting keys and values into its internal configuration structure, but at least one value cannot fit the expected field. This overlaps with ordinary syntax failures without being identical to them. A document may be valid YAML and still give a list to a string field, a mapping to a Boolean field, or a key that the current configuration model does not recognize.
Troubleshoot two layers separately. The first is YAML grammar and hierarchy: tabs, inconsistent indentation, a missing space after a mapping colon, or an unclosed quote. The second is the Mihomo schema: wrong field name, wrong parent, unsupported version, or wrong value type. The Mihomo YAML syntax guide emphasizes case sensitivity, space indentation, same-level alignment, a space after a colon, and hyphens for array elements. The configuration reference defines the actual fields.
Ask two questions: “Is this legal YAML?” and “Does this document match the configuration model of my Mihomo version?” A generic YAML linter can answer only the first.
Do not delete a subscription or reinstall the client when this message appears. Copy the original file, capture the complete error, and record client version, core version, source of the configuration, and the most recent edit. If a subscription update introduced the problem, retain the previous generated file. If a manual edit introduced it, inspect that small diff first. A bounded comparison is more informative than rebuilding a large document from memory.
Start with the first reported line and inspect its parent and predecessor
An error may look like line 42: cannot unmarshal ..., or it may list several lines. Fix the first one first. An early hierarchy mistake can place every later key under the wrong parent and produce many secondary type messages. The reported line is often where the parser can finally prove a contradiction, not necessarily where the typo began. An unclosed quote, missing indentation in a parent, or malformed list item may be several lines above.
- Make a read-only copy of the last known file; do not experiment on the only copy.
- Open the working copy in a plain-text editor that shows line numbers, whitespace, and UTF-8.
- Find the first reported line, then inspect its parent and the preceding list item.
- Compare only that small block with the corresponding first-party field example.
- Make one identified correction, save as a new revision, and run validation again.
If the reported line contains a real proxy, do not paste it publicly. Retain field names and data shapes while replacing server addresses, UUIDs, passwords, and subscription parameters with placeholders. Preserve leading spaces and hyphens: those characters are the evidence needed to diagnose hierarchy. A screenshot that crops the indentation gutter may remove the important part.
| Error fragment | Likely class | Inspection range |
|---|---|---|
| did not find expected key | key, quote, or earlier grammar interruption | current and preceding lines |
| cannot unmarshal !!seq into string | list supplied to a string field | field reference and hyphens |
| cannot unmarshal !!map into bool | mapping supplied to a Boolean field | indentation and expected type |
| field ... not found | unknown key, spelling, or version mismatch | current core documentation |
Visual wrapping in an editor does not change file line numbers, but copying through a chat program can convert tabs and spaces. Inspect invisible characters in the original plain-text working copy, and share only a minimal sanitized block if help is needed.
Correct indentation, tabs, colons, and quotes before schema work
YAML expresses parent-child structure through indentation. Braces cannot rescue an accidentally shifted block in the common block style used by Clash configurations. The official syntax guide requires spaces rather than tabs, left alignment for siblings, a space after a key’s colon, and a hyphen for each array item. A file may choose two or four spaces as a style, but every item at one logical level must align.
This bad fragment contains a tab before the list item and leaves type misaligned with name. Some editors make the columns appear close even though the parser sees different indentation tokens.
proxies:
- name: Example
type: ss
Replace the tab with spaces and align keys that belong to the same proxy mapping:
proxies:
- name: Example
type: ss
Mapping colons also differ from colons that are part of a value. In mixed-port: 7890, a space follows the field colon. Quote a URL, IPv6 value, or text containing # when the documented example or ambiguity calls for it; otherwise the remainder may become a comment. Quotes must be paired, and typographic smart quotes are not ASCII YAML quotes.
Do not globally replace every run of spaces: an automatic indentation repair can alter multiline content, scripts, or rule text. Change only the structural region you have identified and retain the pre-edit copy.
The YAML 1.2.2 specification is useful for general grammar, while Mihomo’s examples are more practical for its fields. Establish valid YAML first, and then test schema-specific types.
After syntax passes, check strings, numbers, Booleans, mappings, and lists
When the message includes cannot unmarshal, read the source and target type. !!seq is a sequence or list, !!map is a key-value mapping, and !!str is a string; integers and Booleans have distinct types as well. The solution is not to remove every hyphen mechanically. The message says that one particular field received a shape different from the structure expected by the core.
For example, this fragment represents a port as a quoted string and a Boolean switch as a list:
mixed-port: "7890"
allow-lan:
- true
After confirming these fields in the configuration reference, the intended shapes are:
mixed-port: 7890
allow-lan: true
Conversely, proxies, proxy-groups, and rules commonly are lists. Do not convert all sequences into one-line strings merely to remove !!seq from an error. Check every field against the documentation for the core version in use. Names are case-sensitive and punctuation matters. A key copied from another client, older core, or converter may be unavailable or valid only beneath a different parent.
- Unknown field: inspect spelling, case, hyphens, version, and parent.
- Sequence into scalar: determine whether the field accepts one value or repeated items.
- Mapping into scalar: look for an extra indentation level that captured later keys.
- Duplicate key: do not depend on implementation-specific overwrite behavior; merge intentionally.
- Null or empty value: follow the field reference to omit it, provide a value, or use an empty string.
For a remotely generated subscription, avoid editing the downloaded cache as a permanent repair because the next refresh can overwrite it. Confirm that the provider serves a Mihomo-compatible format. When local changes are required, use the client’s supported override mechanism so the source subscription remains updateable.
Validate a minimal correction with the matching core before restoring full use
A full configuration can combine subscription proxies, rule providers, DNS, TUN, and scripts. The productive repair is not to delete every suspicious section at once. Preserve the original, create a working revision, and make the smallest change that addresses the first error. If the location remains unclear, remove or comment nonessential sections by halves in an offline copy, preserving valid YAML hierarchy and a written record of each removed region.
Use the same Mihomo version and platform as the client to test the configuration. A common command form is shown below; replace the path with a local sanitized working copy:
mihomo -t -f /path/to/config.yaml
Do not download an unknown “validator core” merely for this step. A generic online YAML checker may upload the complete document and expose credentials, while still checking only grammar. Local validation is safer. If you need outside help, reduce the document to the smallest sanitized block that reproduces the error.
- Keep read-only copies of the original and the most recent known-good file.
- Fix only the first syntax or type error, then rerun the matching validator.
- Address remaining messages in order instead of rewriting the entire file.
- After validation passes, load the copy with System Proxy and TUN initially off.
- Inspect profiles, policy groups, and DNS logs, then make one real connection.
- Replace the production configuration only after stability is shown, retaining rollback.
Definition of done: the configuration check has no errors, the core remains running, expected groups exist, logs show the intended file rather than an older copy, and a real request follows an explainable rule. A successful Save action alone does not meet that standard.
If an unknown-field error remains, report the core version, first complete error, sanitized parent block, and the official reference you followed. Never attach a subscription token, server password, or entire production configuration.
Official sources and version scope
Version numbers, filenames, and interface labels can change. Confirm them in the linked project documentation before making changes.