You save an edited config, the client flashes one line of English, and that is all you get. This turns the common errors into a reference.
First, run a config check
After editing and before importing, let the core validate it:
mihomo -t -d /path/to/config/dir-t is test mode: it checks without running. Its messages are far more detailed than a client dialog, and it usually tells you which line is wrong.
Clash Verge users can run that command against config.yaml in the config directory. Where that directory is:
| Platform | Path |
|---|---|
| Windows | %APPDATA%\io.github.clash-verge-rev.clash-verge-rev |
| macOS | ~/Library/Application Support/io.github.clash-verge-rev.clash-verge-rev |
| Linux | ~/.local/share/io.github.clash-verge-rev.clash-verge-rev |
1. YAML syntax errors
These fail during parsing, and the message usually carries a line number.
found character that cannot start any token
Cause: a tab used for indentation. YAML accepts spaces only.
Locating it: turn on "render whitespace" in your editor; tabs show as arrows.
Fix: replace them all with spaces. In VS Code, Ctrl+Shift+P → "Convert Indentation to Spaces".
mapping values are not allowed in this context
Cause: no space after a colon, or an unquoted colon inside a value.
# wrong
port:7890
name: HK: 01
# right
port: 7890
name: "HK: 01"did not find expected key / could not find expected ':'
Cause: inconsistent indentation.
# wrong: two keys at different indents
proxies:
- name: "A"
type: trojan
server: a.com # ← one space too many
# right
proxies:
- name: "A"
type: trojan
server: a.comfound unexpected end of stream
Cause: an unclosed quote, or a truncated file.
Check that every quote is paired; if the config was downloaded, it may not have finished.
Special characters in a password
# dangerous: # starts a comment, and @ and : can also cause trouble
password: p@ss#word
# right
password: "p@ss#word"2. Field and structure errors
The syntax is fine, but the core does not recognise what you wrote.
unmarshal error / cannot unmarshal !!str into int
Cause: the wrong type, such as a port written as a string.
# wrong
port: "443" # some fields strictly require a number
# right
port: 443Conversely, UUIDs and passwords have to be strings:
uuid: 12345678-1234-1234-1234-123456789012 # may parse as something odd
uuid: "12345678-1234-1234-1234-123456789012" # safeunsupported proxy type: xxx
Cause: the subscription uses a protocol your current core does not support.
Fix: update the Mihomo core. In Clash Verge: Settings → Clash Core → update.
If it is still unsupported after updating, Mihomo genuinely has not implemented that protocol yet and you will need a node using a different one from your provider.
proxy 'xxx' not found
Cause: a policy group references a node name that does not exist.
Common triggers:
- A typo when writing node names by hand
- A subscription update renamed the nodes
- A group name in the extended config does not match the subscription (emoji or spacing differences)
Fix: open the original subscription file and copy the exact name. Or switch to include-all plus filter for automatic collection; see node grouping regex.
rule 'xxx' error: invalid domain
Cause: the rule is malformed.
# wrong
- DOMAIN-SUFFIX,https://google.com,PROXY # no protocol
- DOMAIN-SUFFIX,*.google.com,PROXY # no wildcards
- IP-CIDR,8.8.8.8,DIRECT # IP-CIDR requires a mask
# right
- DOMAIN-SUFFIX,google.com,PROXY
- IP-CIDR,8.8.8.8/32,DIRECT,no-resolverules[N] [xxx] error: unsupported rule type
Cause: a misspelled rule type, or one your core version does not support.
Check the spelling: DOMAIN-SUFFIX not DOMAIN_SUFFIX, IP-CIDR not IPCIDR.
Circular references between policy groups
Symptom: loading hangs, or the message mentions recursion.
Cause: group A's proxies contain B while group B's contain A.
Fix: sort out the hierarchy so references only go one way (upper groups reference lower ones, never the reverse).
3. DNS-related
A domain in default-nameserver
# wrong
default-nameserver:
- https://doh.pub/dns-query
# right: must be plain IPs
default-nameserver:
- 223.5.5.5
- 119.29.29.29The whole purpose of default-nameserver is resolving the hostnames of your other DNS servers, so it cannot itself be a hostname.
Internal names will not resolve
Not an error, just wrong behaviour. The cause is fake-ip catching them.
dns:
fake-ip-filter:
- "+.mycompany.com"
- "*.lan"
- "*.local"See DNS configuration explained.
4. Rule sets and providers
provider xxx: initial failed
Cause: a rule set or subscription failed to download.
Investigation:
The rule set loads but does nothing
Cause: behavior does not match the file contents. This produces no error, it just fails silently.
rule-set xxx not found
The rule set name is referenced in rules but not defined in rule-providers, or the name is misspelled.
5. TUN and permissions
operation not permitted / the TUN switch does nothing
Cause: insufficient privileges, so the virtual adapter could not be created.
Fix:
- Windows / macOS: install "service mode"
- Linux:
sudo setcap cap_net_admin,cap_net_bind_service=+ep /path/to/mihomo
address already in use
The port is taken.
# Windows
netstat -ano | findstr :7897
tasklist | findstr <PID># Linux / macOS
lsof -i :7897Change the port or stop the process holding it.
6. A fast way to locate the problem
When the config is long and the error carries no line number, bisect it:
A minimal working config to use as a baseline:
mixed-port: 7897
mode: rule
log-level: info
proxies:
- name: "TEST"
type: trojan
server: example.com
port: 443
password: "pwd"
proxy-groups:
- name: "PROXY"
type: select
proxies: ["TEST", DIRECT]
rules:
- MATCH,PROXYIf that loads, your environment is fine and the problem is in your config's content.
7. The error reference table
| Error keyword | Cause | Fix |
|---|---|---|
cannot start any token | A tab was used | Replace with spaces |
mapping values are not allowed | No space after a colon, or a colon in a value | Add a space, or quote it |
did not find expected key | Inconsistent indentation | Align the indentation |
unexpected end of stream | Unclosed quote or incomplete file | Check quotes, download again |
unmarshal error | Type mismatch | Numbers unquoted, strings quoted |
unsupported proxy type | Protocol unsupported | Update the core |
proxy not found | Node name reference wrong | Copy the exact name from the subscription |
unsupported rule type | Rule type misspelled | Check hyphens and capitalisation |
invalid domain | Malformed rule content | Remove protocol prefixes and wildcards |
provider initial failed | Download failed | Check the url, add proxy and UA |
address already in use | Port taken | Change the port or stop the process |
operation not permitted | Insufficient privileges | Install service mode, or setcap |
| Rule set silently ineffective | behavior mismatch | Open the cache file and compare |
8. Prevention
In short
mihomo -t -d directoryis the single most useful command; its errors beat the client's- The three YAML traps: tab indentation, a missing space after a colon, and an unclosed quote
proxy not foundusually means a name mismatch — copy it from the subscription- A rule set that fails silently means the behavior is wrong
- When you cannot locate it, bisect the config
Related: the YAML structure explained and the Merge extended config.
Related docs
A Clash / Mihomo config taken apart from top to bottom — ports, mode, DNS, proxies, proxy-groups, rules and rule-providers — with a minimal working config you can paste straight in.
What each policy group actually does, when to use it, the parameters that matter, plus a grouping structure you can copy wholesale and Mihomo's include-all and filter options.
Editing the downloaded config gets undone at the next update. How Clash Verge's extended config works: prepend/append/override syntax, merge order, and a set of useful snippets.