Separate the provider, policy group, and selected proxy

proxy-providers define where a collection of proxy entries comes from. A provider may read a remote response, a local file, or inline configuration. A proxy-group consumes that collection with use and decides whether selection is manual, latency based, or failover oriented. The item finally chosen by the user is a concrete proxy or another group. These layers can have similar names in a GUI, but they do different jobs.

This distinction gives every failure a sensible starting point. A provider that refreshed successfully only proves that Mihomo fetched and parsed content. It does not prove that every remote server is reachable. If a group is empty, inspect its use reference, regular expressions, and excluded protocol types. If the entries are present but time out, inspect connectivity and the health-check target instead.

Protect the source URL: subscription URLs often contain an account token. Replace it with a placeholder in examples and redact the query string in screenshots or logs.

Choose an HTTP, file, or inline source

A remotely maintained subscription normally uses type: http with a url, a unique local cache path, and an update interval. A file provider reads a local file; it does not turn that file into a remotely updating subscription. An inline provider keeps entries in the main configuration and is best reserved for a small set that you maintain yourself.

YAMLproxy-providers:
  main-subscription:
    type: http
    url: "https://provider.example/sub?token=REDACTED"
    path: ./providers/main.yaml
    interval: 21600
    proxy: DIRECT
    size-limit: 10485760
    header:
      User-Agent:
        - "mihomo"

The provider's proxy controls how the update request itself reaches the subscription server. DIRECT is not universally correct: a source reachable only through an existing route needs an appropriate proxy or group. size-limit is measured in bytes, so the example permits 10 MiB; the limit constrains the response but does not establish trust. Give every provider its own cache path so that two updates cannot overwrite the same file.

Filter names and protocol types deliberately

filter keeps entries whose names match a regular expression, while exclude-filter removes matching names. Those name filters may be applied at the provider level or when a proxy group imports a provider. A provider's exclude-type removes protocol types from that provider. Proxy groups also expose a field with that name, but the official group reference limits it to directly imported outbound proxies; it does not remove provider entries brought in with use. Keeping one source and filtering its names per regional group is usually clearer than downloading duplicates.

YAMLproxy-groups:
  - name: Japan
    type: select
    use:
      - main-subscription
    filter: '(?i)(Japan|Tokyo|Osaka|日本|东京|大阪|\bJP\b)'
    exclude-filter: '(?i)(expired|remaining|official|plan)'

The expression examines the label supplied by the provider; it does not verify the server's physical location. A naming change can therefore empty a previously healthy group. Quoting also matters because YAML and the regular-expression engine both interpret backslashes. Test one condition at a time in a disposable group before applying a complex expression across your configuration.

Understand what a health check proves

A provider health check sends a request through each proxy to a chosen URL. Mihomo can evaluate latency, timeout, and an expected HTTP status with fields such as enable, url, interval, timeout, lazy, and expected-status. The endpoint should be stable, small, and reasonably accessible from every candidate exit.

YAMLhealth-check:
  enable: true
  url: https://www.gstatic.com/generate_204
  interval: 600
  timeout: 5000
  lazy: true
  expected-status: 204

A pass means that the proxy reached that test URL at that moment. It does not guarantee that streaming, gaming, or a particular API will work. Conversely, a failed result can mean the test host is blocked from one exit even though the tunnel is valid. Very short intervals multiply traffic across every entry. Lazy checking reduces idle work, but the first use of a dormant provider may need time to obtain fresh results.

Feed providers into select, url-test, or fallback groups

A provider does not route traffic on its own. Use select when a meeting or account session needs a stable, manually chosen exit. Use url-test when automatic choice based on a probe is appropriate. Consider fallback when an ordered primary-and-backup policy matters. Group probes and provider health checks exist at different layers; a dashboard may show both without either being redundant.

Use caseGroup typeMain consideration
Meeting or fixed exitselectAvoid automatic mid-session changes
General browsingurl-testProbe results are service-specific
Primary and backupfallbackOrder and recovery behavior

Keep a minimally filtered “all nodes” group as an observation point. If a regional group becomes empty after an update while the baseline group remains populated, the likely cause is its expression or type filter—not the remote source itself.

Verify one layer at a time

  1. Refresh the provider manually and inspect its timestamp, response size, and parse log.
  2. Confirm raw entry names and counts in an unfiltered temporary group.
  3. Add the include expression, exclusion expression, and protocol exclusion one by one.
  4. Run health checks and distinguish an empty group, a failed probe, and an unavailable business service.
  5. Only then tune the group type, interval, tolerance, or failover behavior.

If the downloaded body is an HTML sign-in page, an authorization error, or an empty response, fix the source rather than the regular expression. If the cache path is unwritable, correct that filesystem problem. If only one probe endpoint fails, compare it with another stable endpoint before discarding every node. Consult the first-party proxy-providers reference and proxy-groups reference for the current field definitions.

Keep a rollback copy and record four separate outcomes: the source refreshes, the group contains entries, the health check passes, and the intended service works. That small discipline turns future provider renames and node rotations into bounded configuration changes instead of guesswork.

Official sources and version scope

Version numbers, filenames, and interface labels can change. Confirm them in the linked project documentation before making changes.