On this page
First confirm that domain-pattern validation is failing
This article addresses one specific symptom: the same configuration starts on Mihomo v1.19.29 or earlier, but after upgrading to v1.19.30 the core reports Parse config error: invalid domain and exits during configuration loading.
Official issue #3116 recorded the change in a Linux Docker environment and traced it to domain patterns in sniffer.skip-domain and dns.fake-ip-filter. v1.19.30 includes stricter validation of Clash-style domain wildcards. This is not a failed node and cannot be bypassed by switching the proxy mode to Direct.
If the log says Invalid YAML, unsupported field, or proxy not found, or if the core starts but websites will not load, the failure occurs at another stage. Troubleshoot that error directly instead of changing every configuration failure to the wildcard syntax in this article.
Branch from the first error
| Log or symptom | More likely stage | Does this article apply? |
|---|---|---|
| Parse config error: invalid domain | Domain-pattern validation | Applies when it appears after upgrading to v1.19.30 |
| Invalid YAML or indentation error | YAML structure | Does not apply; fix the syntax first |
| proxy / group not found | Policy-group or rule reference | Does not apply; restore the missing reference first |
| The core starts, but only one domain fails | DNS, rules, or network | Does not apply; inspect connection records first |
Save the working configuration and its generation source first
Before searching for asterisks, separately save the current final configuration, the client's Profile, Merge or override, and the subscription-conversion template. Backing up only config.yaml in the runtime directory is not enough: the invalid source pattern will overwrite the fix the next time the client updates the subscription.
If the old core is still forwarding traffic, do not restart the service or refresh the subscription repeatedly. Preserve the working state first, then copy the error log, client version, and actual Mihomo version. Remove the subscription token, node passwords, controller secret, and private domains from screenshots and configuration copies.
Prepare a rollback path
Record the actual core version
Confirm on the client's About page, in the startup log, or with mihomo -v that v1.19.30 is running; do not substitute “latest” for the version number.
Export the final configuration
Save the YAML actually loaded by the core, plus the Profile, Merge, override, or conversion template.
Keep the previous core release
Keep only the v1.19.29 file from the official Release that has already been verified on this machine as a temporary fallback.
Hold other variables constant
Do not change the subscription, node, DNS mode, or TUN setting at the same time during troubleshooting; avoid introducing a second failure.
Locate the first invalid domain pattern
Test the final configuration first with the v1.19.30 build you intend to run. The command used in the official issue is mihomo -t -f. A successful test only means the current core can parse and initialize the configuration; it does not start the proxy or prove that nodes work.
The stable v1.19.30 release may report only the generic invalid domain error. Search the final YAML and any referenced local files for asterisks, starting with sniffer.skip-domain and dns.fake-ip-filter, which the issue confirmed as problematic. Retest after each correction so the core can point to the next error.
mihomo -v
mihomo -t -f /path/to/config.yamlgrep -R -n '\*' /path/to/config.yaml /path/to/rules 2>/dev/nullrrn-sw-*, a*.example.com, or *a.example.com
The asterisk is mixed into the same label, a pattern that v1.19.30 explicitly rejects.
*.example.com or time.*.com
The asterisk occupies an entire label, so the form itself is valid; continue to the next item.
example.com., a..example.com, or leading or trailing spaces
Strict validation also rejects a trailing dot, an empty label, and leading or trailing whitespace.
No asterisk can be found
Check for plus signs, trailing dots, empty labels, and the final configuration generated by the client; do not search only the original subscription.
Distinguish the three valid domain wildcard forms
Mihomo documentation calls this Clash-style domain wildcard syntax and explicitly notes that it differs from DOMAIN-WILDCARD in routing rules. Do not copy a seemingly similar asterisk expression from a routing tutorial directly into fake-ip-filter or skip-domain.
The key is not whether the asterisk comes first or last; it must occupy an entire dot-delimited label. time.*.com is valid because the middle label contains only the asterisk. rrn-sw-* is invalid because the asterisk and rrn-sw- share the same label.
Choose syntax based on the intended match scope
| Valid syntax | Match scope | Does not match |
|---|---|---|
| *.example.com | Exactly one subdomain level, such as a.example.com | example.com、b.a.example.com |
| +.example.com | The root domain and subdomains at any depth | Other suffixes |
| .example.com | Subdomains at any depth | The example.com root domain |
| time.*.com | Exactly one complete label in the middle | time.com、time.a.b.com |
| * | A single-label hostname with no dot | A fully qualified domain name containing dots |
rrn-sw-*
a*.example.com
*a.example.com
a*b.example.comRewrite the pattern according to its real intent; do not make a mechanical replacement
If the intent is to match one or more subdomain levels under a fixed root domain, choose among the asterisk, plus sign, and dot-prefix forms. If the original intent is to match a group of LAN hosts beginning with rrn-sw-, Clash-style domain lists have no partial-label wildcard equivalent to rrn-sw-*; explicitly list the real hostnames instead.
Do not mechanically change rrn-sw-* to *.rrn-sw, rrn-sw.*, or +.rrn-sw. They describe different label structures and may pass validation without matching the intended hosts. List the actual queried names first, then make every configuration entry explainable in terms of its coverage.
sniffer:
skip-domain:
- "rrn-sw-01"
- "rrn-sw-02"
dns:
fake-ip-filter:
- "+.example.com"
- "time.*.com"Invalid patterns and actionable remedies
| Original intent | Do not change it this way | Actionable remedy |
|---|---|---|
| Match short hostnames beginning with rrn-sw- | Keep using rrn-sw-* | List the actual hostnames, such as rrn-sw-01 and rrn-sw-02 |
| Match one subdomain level under example.com | a*.example.com | Use *.example.com |
| Match the root domain and all subdomains | *example.com | Use +.example.com |
| Match all subdomains but not the root domain | Use *.example.com and assume it includes multiple levels | Use .example.com |
Validate the fix with the same v1.19.30
After saving a candidate copy, test it with the same v1.19.30 build. If invalid domain remains, address the next error; do not overwrite the only working configuration just because the first error disappeared. Let the client load the candidate and restart the core only after every error is cleared.
A running core is only the first acceptance check. Visit a domain that should match fake-ip-filter, one that sniffer should skip, and an ordinary public domain, then inspect the DNS results and connection records. A syntax-valid pattern with the wrong scope is still not a completed fix.
Promote the candidate in rollback-safe order
Test the candidate copy
Run mihomo -t -f until v1.19.30 explicitly reports that the configuration test passed.
Save the original before replacing it
Keep the previous working YAML; do not overwrite the only original while the client is running.
Reload or restart the core
Confirm that the log shows v1.19.30 has started and is not still reading an old process or configuration.
Retest real matching behavior
Use known domain requests to check DNS, sniffing, rule matches, and final page access.
Completion criteria
- The final configuration passes v1.19.30 test mode
- The core starts and remains running with no new configuration parsing errors
- The listed LAN hosts bypass sniffing or Fake-IP as intended
- One-level, any-depth, and root-domain matching scopes agree with the selected syntax
- Ordinary public domains and node connections are not harmed by the broadened rules
- The original configuration, generation source, and old-core fallback file remain available
Fix the generation source if the error returns after an update
If manual changes allow the core to start but refreshing the subscription, switching Profile, or restarting the client brings the same error back, the invalid pattern comes from a conversion template, remote configuration, Merge, or override. Stop editing the temporary runtime file repeatedly. Compare the final YAML before and after the fix to find the layer that restores the old value.
If you control the subscription or converter, fix the template and regenerate it. If you control only the client, replace the complete list in a managed Merge or override, then confirm that the final configuration remains valid after an update. Do not upload a subscription containing a token to an unfamiliar converter site, and do not use one overly broad suffix to cover every unknown case.
The error returns after every subscription update
Revise the subscription conversion template or upstream configuration, then generate a new candidate.
The error returns after switching Profile
Check the Merge, Script, and local overrides for each Profile separately.
The file on disk is changed, but the core still reports the old value
Confirm the path actually loaded, the running process, and the final configuration generated by the client.
The configuration starts only with a broad suffix
List the required hosts and record any gaps first; do not treat expanded scope as a long-term solution.
Roll back safely first if an immediate fix is not possible
If an uncontrollable source keeps generating the configuration and cannot be corrected promptly, disable TUN or the system proxy to restore direct system connectivity, then restore the backed-up configuration. If a workload truly depends on it, temporarily return to the locally verified v1.19.29 and retest v1.19.30 after the generation source is fixed.
A rollback restores service; it does not prove the old syntax is correct. The strict-validation commit in v1.19.30 is already in the current stable release, while the commit that adds a more detailed error path came later. Do not turn “the old version did not report an error” and “a newer Alpha is easier to diagnose” into a permanent version strategy.
Restore a known working state
Stop the failing core retries
Disable client interception first so system traffic does not keep pointing to a local port with no running service.
Restore the configuration backup
Restore the Profile, final YAML, and required overrides; do not import an entire directory from an unknown source.
Temporarily roll back the core if necessary
Use only the official v1.19.29 for the architecture verified on this machine, and record the reason and date of the rollback.
Schedule a retest on the same version
After fixing the generation source, return to v1.19.30 and repeat the configuration test, startup, and real-domain validation.
