Preface
When a Clash configuration grows, its rules list can become difficult to review. New exceptions get added at the bottom, old entries remain after a service changes its domains, and a small edit can accidentally change which policy handles unrelated traffic. Rule providers help separate reusable rule data from the main routing configuration. Instead of maintaining every domain or CIDR inline, you store a related set of rules in a provider file and reference that provider from the main rules section.
This guide focuses on custom providers with Mihomo, the core used by many current Clash clients, including Clash Verge Rev. You will build a remote provider, define the proxy group that its rules should use, set a refresh interval, control rule priority, and test changes without losing track of the source. Provider support and available options can vary by core and client version, so check the active core’s documentation when adapting the examples.
What You’ll Build
A maintainable rule provider for work-related domains, routed through a named proxy group, with a clear refresh strategy and a safe way to troubleshoot changes.
1Understand the Provider Model
A rule provider is a named collection of rules loaded from a local file or downloaded from a URL. The main configuration declares where the collection comes from and how its contents should be interpreted. A separate rule then connects the provider to a policy, such as a proxy group, DIRECT, or REJECT. Keeping those responsibilities separate makes it easier to update the rule data without rewriting the policy structure.
For example, a provider called work-sites can contain domains used by company tools. The main configuration can send matches from that provider to a group named Work. The provider does not create the group, select a proxy node, or decide the route on its own. Those parts must already exist in the profile.
Choose a behavior that matches the file
Mihomo’s provider behavior tells the core what kind of entries to expect. Use domain for domain names, ipcidr for IP address ranges, and classical when the payload contains full Clash-style rule expressions. Do not mix entry types in a provider that declares a narrower behavior. A domain provider is not the place to paste a full line such as DOMAIN-SUFFIX,example.com,Work; the destination policy is specified in the main rule that references the provider.
- Domain: Use entries such as
example.comor+.example.comwhen a whole domain and its subdomains should match. - IP CIDR: Use valid network ranges such as
192.0.2.0/24. These rules match IP traffic, so confirm how your core resolves domain names before relying on them for host-based routing. - Classical: Use complete rule expressions, such as
DOMAIN-SUFFIX,example.com, when the list needs mixed rule types or more specific matching logic.
Use an appropriate source
An HTTP provider is useful when you keep a list in a repository or another stable web location. A file provider is useful for rules maintained locally alongside a profile. A remote URL should return the raw rule file itself, not a repository webpage, sign-in page, or HTML error response. For a private repository, also account for authentication and the possibility that a client or core will not be able to fetch the file in your network environment.
Pro Tip: Start with One Purpose
Keep providers focused. A small provider for work domains is easier to review and test than one file combining work, streaming, advertising, and IP ranges.
2Build the YAML Configuration
The following example shows an HTTP provider for a domain list. Replace the example URL with a stable raw-file URL that you control. The provider name is a configuration key: use the exact same spelling in the matching RULE-SET rule. The path identifies the local cache file used by the core, and interval sets the refresh interval in seconds for a remote provider.
In this example, the provider checks for updated content every 86,400 seconds, or once per day. An interval is not a guarantee that a source will be reachable or that a changed file is valid; it is simply the core’s refresh schedule. Choose a value that suits how often the list changes and how dependable the hosting is. Extremely short intervals add needless requests and may cause problems if a host applies rate limits.
With format: yaml, the remote file can use a YAML payload. For a domain provider, it might look like this:
Keep the payload valid YAML. Indent list items consistently, quote entries when they contain characters that YAML might interpret specially, and do not add a proxy policy to each domain entry. If you prefer a plain-text rule file, confirm the supported format for your Mihomo version and make the provider declaration and payload format agree. A file that is valid YAML but has the wrong structure can still fail to load as a provider.
Reference an existing proxy group
Define the destination group in proxy-groups, then use that group name in the rule referencing the provider. The group’s name must match exactly, including capitalization and spaces. The example below assumes Work-Node is already available as a proxy or is otherwise valid in your profile; replace it with an option that exists in your configuration.
The provider is named work-sites, while the routing target is Work. These are different names with different roles. The first identifies the rule collection; the last field in RULE-SET,work-sites,Work identifies where matching traffic goes. You may point multiple providers at the same group, or use different groups when separate categories need different routing choices.
Put specific rules before broad rules
Clash evaluates routing rules from top to bottom and uses the first match. A provider rule placed below a broad matching rule may never be reached. For example, if a preceding rule sends all traffic to DIRECT, the work provider after it cannot send work domains to the Work group. Put narrow exceptions and provider rules above broader rules, and keep the final catch-all such as MATCH,PROXY at the end.
Common Priority Mistake
A provider can load successfully and still appear ineffective if an earlier rule matches the same traffic. Check rule order before changing the provider contents.
3Manage Updates and Troubleshoot Matching
Treat custom rule files as configuration code. Keep a known-good copy, make one meaningful change at a time, and record why a domain or network range was added. If you use Git, store the provider file in a repository, review the diff before publishing, and use a commit message that describes the routing change. This makes it much easier to identify which edit introduced a syntax error or an unexpected match.
Before deploying an update, validate the YAML structure and review the entries for accidental duplicates, overly broad suffixes, and stale domains. A rule such as +.example.com can cover many subdomains; confirm that this breadth is intentional. For IP ranges, verify the CIDR prefix carefully. A typo that expands a range may affect substantially more traffic than intended.
Roll out changes in small steps
- Save a backup of the active profile and the current provider file.
- Update only the relevant provider entries, then check the file’s syntax and expected format.
- Publish the file to the configured URL or place it at the configured local path.
- Reload the profile or provider in the client, then check the core’s logs for download, parsing, or rule errors.
- Test a known matching domain and a known non-matching domain. Confirm the selected rule and policy in the client’s connection or rule log view.
- If the result is unexpected, revert the provider file or rule order first, then repeat the test with one change at a time.
GUI labels differ between Clash Verge, Clash Verge Rev, and other clients. Look for the active profile’s rule-provider status, core logs, and connection details rather than relying on a particular menu name. Also confirm that the client is running a Mihomo-compatible core; a configuration accepted by one core may not be supported by another.
Diagnose common failures
- Provider download fails: Open the configured URL in a browser or use a command-line HTTP client to confirm that it returns the raw file. Check connectivity, DNS, TLS, access controls, and whether the host requires authentication. A successful browser login does not mean the core can fetch a private URL.
- Provider does not load: Confirm that the path is writable and that the configuration uses a supported provider type and format. Inspect the core log for YAML parsing errors, incorrect indentation, an invalid payload, or a mismatch between
behaviorand the rule entries. - The profile reports an unknown provider: Compare the key under
rule-providerswith the provider name inRULE-SET. Check spelling, hyphens, capitalization, and whether the rule references a provider that is actually declared in the active profile. - The expected traffic uses another route: Check the rule list from top to bottom. Look for an earlier domain, IP, or catch-all rule that already matches. Confirm that the rule’s target group exists and that the group contains usable options.
- Changes do not appear: Verify the configured refresh interval, trigger a manual update if the client offers one, and inspect the provider’s update time and logs. The local cache can continue to contain the previous version if a new fetch fails.
Use the client’s rule matching or connection inspection tools to test actual traffic. A browser cache, DNS cache, an already-open connection, or another matching rule can make a routing change appear inconsistent. Close and reopen the test connection when appropriate, and compare the observed match with the exact provider entry and rule order.
Frequently Asked Questions
Can I use a local rule provider instead of a URL?
Yes, Mihomo supports local file providers, provided the active core and client support the configuration you use. A local file avoids a remote fetch, but you must update the file yourself and place it at the configured path. Confirm the file’s location, permissions, and format, then reload the profile or provider so the core reads the new content.
Does the refresh interval update a provider immediately?
No. The interval defines a periodic refresh schedule for a remote provider; it does not guarantee an instant update after you publish a change. A client may offer a manual provider-update action. Otherwise, wait for the scheduled refresh or reload as appropriate, then check the core logs and provider status to verify that the new version was fetched.
Can a provider choose different proxy groups for individual entries?
With a domain or IP CIDR provider, the policy is normally supplied by the RULE-SET line in the main configuration. If entries need different policies, split them into separate providers and reference each with its own rule, or use a suitable classical provider containing full rule expressions. In either case, preserve intentional rule priority and verify the format supported by your core.
Will the same provider YAML work in every Clash client?
Not necessarily. Clients are interfaces around a routing core, and provider options can depend on the core version. Check which core the client is running, use syntax supported by that core, and test the profile before relying on it. When an option is rejected, consult the core’s documentation and logs rather than assuming the client’s name alone determines compatibility.