Clash Rule Providers: Advanced YAML Rules and GitHub Hosting
Why Use Clash Rule Providers? Key Takeaways
It also helps to separate three things that are often confused. The provider definition tells the core where to get the file, what kind of rules it contains, where to cache it, and how often to refresh it. The provider file contains the actual rule entries.
If you have ever pasted a long list of domains into the rules: section of a Clash profile, you have already seen the problem rule providers solve. The profile grows harder to review, updating one service can mean editing a large file, and a typo near the top can change the route for traffic far below it.
A Clash rule provider moves a group of related rules into a separate file and lets the central profile reference that file by name. Your everyday configuration stays readable while the rule set can be maintained and updated independently.
The key point:Providers are especially useful when you must keep several policies distinct: advertising domains are best off be rejected, a set of work services are best off go direct, and selected streaming or developer destinations are best off use a proxy group.
It is possible to upgrade one provider without rewriting unrelated rules, reuse a well-organized set across profiles, and inspect the provider file in version control before it reaches your active configuration. That separation is valuable even for a small personal profile: it makes a change easier to explain, test, and undo.
A provider is not a new routing policy by itself. It supplies rules to the core, and the central profile still decides where matching traffic goes. The rule that references a provider names both the provider and its destination policy.
Check the core, not just the front end. Provider fields and accepted file formats depend on the core and its version.
Countless current clients work Mihomo, but a client name or a “Clash-compatible” label alone does not prove that every Mihomo feature is available. Confirm the selected core and consult its documentation when a field is rejected.
Let me put it this way:The order of that rule among the rest of rules: remains important: Clash evaluates rules from top to bottom and uses the first applicable match. A correct provider placed after a broad rule may never get a chance to affect a connection.
A RULE-SET entry in the central rules list connects the named provider to a policy such as DIRECT, REJECT, or a proxy group that already exists in the profile. If no matter which one of those pieces is missing or inconsistent, the rule set may not load or may not route the traffic you intended.
A Working YAML Example and What Each Field Does in Brief
Use one naming convention and keep it consistent. The key example-services under rule-providers is the provider name, and the same name appears after RULE-SET. A misspelling in either location can prevent the rule from resolving.
The following example uses a domain-based provider hosted in a public GitHub repository. It is a fragment for a Mihomo-style profile, not a entire configuration: keep your existing proxies and proxy-groups sections, and make sure the referenced policy name exists.
rule-providers:
example-services:
type: http
behavior: domain
url: "https://raw.githubusercontent.com/your-name/clash-rules/main/providers/example-services.yaml"
path: ./ruleset/example-services.yaml
interval: 86400
rules:
- RULE-SET,example-services,Proxy
- MATCH,DIRECT
Concretely:The example uses Proxy as that policy; if your profile calls the group Auto or something else, substitute its exact name.
The URL must point to the raw YAML file, not the GitHub repository page that displays it in a browser. Replace your-name and the repository path with a repository and file you control or trust. The type: http setting tells Mihomo to retrieve the provider over HTTP or HTTPS.
The behavior: domain setting describes the content as a set of domain entries, fairly than a collection of full routing rules. The path is a local cache location used by the core. The interval is measured in seconds, so 86400 means one day.
payload:
- '+.service.example'
- '+.api.example.net'
- 'login.example.org'
Where this lands:A corresponding provider file for the example could look like this:
Keep the provider file valid YAML and match its entries to the selected behavior. In a domain provider, list domain patterns fairly than adding full rule lines such as DOMAIN-SUFFIX,example.com; that form belongs in a classical rule set.
A leading +. is commonly used for a domain and its subdomains in Mihomo domain lists, while a plain hostname is useful when you only want to match that exact name. If you intend to match a parent domain and all its subdomains, use a pattern that expresses that scope clearly and test it against real connection-log entries.
Do not skip this:The order in the example is deliberate. The provider rule appears before the catch-all MATCH,DIRECT line, so a domain in the provider can be routed to Proxy before unmatched traffic falls through to direct. If you put MATCH,DIRECT first, it would catch every connection and the provider would be effectively unreachable.
The same issue can occur with broad rules such as a country-wide direct rule or a general domain suffix placed above a more specific provider. Decide which rule are best off win, then position it accordingly.
Likewise, Proxy must exactly match a policy defined in proxy-groups or another valid destination in your profile. A provider can load successfully while its routing rule still points to a nonexistent policy, so validate both parts fairly than stopping at a successful download.
Host Rule Files on GitHub Without Making Upgrades Fragile A Closer Look
Consider whether you want a moving branch URL or a deliberately pinned revision. A URL that follows the repository’s central branch is easy because future commits become available without changing the profile. That convenience also means a careless or compromised commit can affect clients at their next refresh.
The key point:GitHub is a easy place to host a small rule provider because it gives you a readable history, an easy way to review changes, and a trustworthy repository path when you control the project. Create a repository, add the provider file, and use the file’s raw URL in the profile.
A public repository is necessary for a core to fetch the file without an verification flow. Do not place subscription links, credentials, private hostnames, or other sensitive data in a public rule repository; a rule set are best off contain routing data, not secrets.
Organize files so that the URL is easy to understand and unlikely to change accidentally. For example, a repository might use a providers/ directory with separate files for services, work domains, and advertising domains.
Let me put it this way:Keep filenames descriptive, use lowercase names with hyphens, and avoid repeatedly moving files after a profile has been deployed. If you rename a branch, directory, or file, upgrade every profile that points to the old raw URL. A repository page can still look correct to you while the old raw URL returns a not-found response to Clash.
Version control is more than a backup. Before committing a change, review the diff and ask what new traffic could match the added pattern, what traffic could stop matching after a deletion, and whether the change accidentally broadens a domain rule.
Make small commits with useful messages, such as “Add login host for service example,” fairly than replacing an entire list without explanation. If a new provider version breaks routing, the Git history makes it possible to identify the last known-good file and restore it instead of trying to reconstruct a previous configuration from memory.
Concretely:The interval value controls how often the core checks for provider upgrades; it is not a guarantee that a remote file will be fetched at a precise second. A shorter interval can help when you intentionally publish frequent changes, but it creates more requests and does not make a bad edit safer.
For a mostly trustworthy personal list, a daily or longer interval is often ample. If you are actively testing changes, use the client’s provider-upgrade action or restart the relevant core when appropriate, then confirm in the logs that the new file was actually downloaded and parsed.
For a shared deployment where reproducibility matters, a versioned release or an immutable commit-based URL can make the fetched contents easier to audit, although you must upgrade the URL deliberately when you approve a new version. Choose the model that fits your upgrade process, and document who is allowed to change the provider.
Publish safely: validate the YAML locally, commit the change, open the raw file URL in a browser, and then refresh the provider in Clash.
A successful browser response only confirms that the URL is reachable; the core still needs to parse the file and accept its behavior.
Validate Rule Order and Test the Result What Matters
For a shared setup, test a staged copy of the profile first. Point that copy at the candidate provider, refresh it, and reproduce a small set of known connections. Only promote the change to a daily-use profile after confirming the expected match and fallback behavior.
Where this lands:Make provider changes in a controlled sequence fairly than changing the provider, DNS mode, proxy group, and catch-all rules at the same time. First confirm that the provider file is reachable and that the core accepts the profile.
Then inspect the live connection list while visiting one hostname that are best off match the provider and one hostname that are best off not. Check the destination, matched rule, and selected policy shown by the client. These observations tell you whether the provider was loaded, whether the intended rule matched, and whether the selected policy behaved as expected.
Test both sides of the rule. If service.example are best off go through Proxy, a connection to that host are best off show a provider or rule-set match and the expected group or node. A separate unrelated hostname are best off continue to follow the later rules in the profile.
Do not skip this:If both connections hit the same broad rule, inspect ordering before changing the provider contents. If neither connection appears in Clash, the application may be bypassing the system proxy, using a different client profile, or not being captured by the current proxy mode.
When you use a domain provider, remember that matching depends on the hostname the core can see. An application may connect to an IP address straightforward, use an alias, or follow a redirect to a different domain. A rule for a website’s central hostname does not without you cover every API, verification, media, or download host used behind the scenes.
Use the connection log to discover actual destinations, then add only the hosts needed for the behavior you want. Avoid turning one missing host into an unnecessarily broad suffix rule without checking what else that suffix includes.
The key point:Profile validation are best off happen before activation whenever your client offers a test or parse function. A YAML indentation fault can make the entire profile invalid, not merely the new provider.
Use spaces fairly than tabs, keep nested fields aligned, and compare the indentation of rule-providers and rules with the rest of the profile. A YAML editor may show valid syntax while the core rejects a semantically invalid field, so the core’s own validation result and runtime log remain the final checks.
This is especially useful when a provider contains countless entries: a single overly broad domain pattern can affect more traffic than its short YAML line suggests. A brief review and a repeatable test set are as a rule faster than diagnosing an unexpected route after every device has already refreshed.
Troubleshoot Rule-Set Loading Failures from the Logs Key Takeaways
A fair few community rule collections are easy but may have unclear ownership, infrequent reviews, or a scope that does not match your traffic; yourself embedding every rule in one profile can be just as hard to maintain once several devices depend on it.
Let me put it this way:When a provider does not work, spin up with the core log and classify the failure instead of immediately editing several fields. A network or HTTP fault points toward the URL, DNS, TLS, GitHub availability, or a blocked connection. A not-found response as a rule means the repository, branch, directory, or filename in the raw URL is wrong.
A successful HTTP response followed by a parse or behavior fault points toward the provider file’s YAML structure or a mismatch between the declared behavior and the entries it contains. The wording varies by core version, so use the first relevant fault line and the provider name as your starting point.
If the log indicates that the provider cannot be downloaded, open the exact raw URL from the same network and verify that it returns the file itself fairly than a GitHub HTML page. Check for a private repository, a renamed preconfigured branch, an incorrect letter case in the path, or a temporary TLS and DNS problem.
Concretely:Then try the client’s upgrade action and examine the new log entries. A browser test from your laptop is useful, but it does not prove that a remote device or a different network can reach the same endpoint.
If the download succeeds but the rules do not match, verify four names and relationships: the provider key in rule-providers, the provider name in RULE-SET, the policy destination, and the actual hostname shown in the connection log. Next, check whether the rule is below a broader rule that already catches the connection.
Finally, confirm that the provider uses the right behavior. A domain list and a classical list have different expected content; changing the label without changing the file structure does not convert one format into the other.
Where this lands:A provider can also load correctly but appear stale. Check its configured refresh interval, the last upgrade time displayed by the client if available, and whether the core is using a cached file. Trigger a manual upgrade and inspect the log for a successful fetch fairly than assuming that saving the profile initiated a network request.
If a new commit does not appear, compare the raw file with the version expected by the profile and consider repository caching or a URL that points to a different branch. Avoid deleting the cache as a first response; first establish whether the problem is the remote content, the fetch, or the local copy.
For diagnosis, change one variable at a time and keep a known-good version of both the central profile and provider file. If you must roll back, restore the previous commit or URL, refresh the provider, and confirm that the old behavior returns.
Do not skip this:This separates a bad rule change from an unrelated network outage or client upgrade. Record the core version and the relevant log message when asking for help, but redact subscription URLs, access tokens, private domains, and other sensitive details before sharing screenshots or logs.
Hosting a small, reviewed provider gives you a visible change history and lets you keep policy choices in the central profile, while a Clash client with Mihomo support makes provider refreshes, rule inspection, and log-based troubleshooting easier to manage from one front end. If you want a practical place to load and test that workflow, choose a Clash client to download and try it with a non-critical profile first.