First, identify where the failure occurs

Updating a Clash subscription involves more than downloading a file. The client requests the subscription URL, parses the response, saves the configuration or proxy list, and then loads it into the core. A failure at any stage may show up simply as “Update failed.” Note the exact error, update time, and active configuration name before trying again; this is more useful than repeatedly clicking Update.

There are also two different kinds of subscriptions: complete remote configurations managed by a GUI client, and proxy providers managed through proxy-providers in a mihomo configuration. The client typically stores the refresh interval for the former; the latter uses its own interval field. These are separate timers, so changing one does not change the other.

Error or symptomCheck firstNext step
401、403Token, account permissions, and server access policyCheck the link status in your provider account
404、410Outdated endpoint, revoked link, or incomplete URLCopy the current subscription URL again
429Too many requests or simultaneous refreshes across devicesStop retrying and wait as directed by the server
timeout、EOFNetwork route, TLS, and intermediary devicesCompare direct and proxied requests
yaml、unmarshalResponse format and field typesMake sure the response is actually in the expected configuration format
Update succeeds, but loading failsCore compatibility and policy-group referencesCheck configuration validation and load logs

Expired links and server rejections: check the status code first

Copy the URL again; don't assemble parameters by hand

Sign in to your subscription provider and check your plan, data allowance, and expiration date. Then copy the subscription URL for Clash or Clash Meta. Resetting a subscription token may invalidate the old URL immediately; if the client still has the old one, scheduled refreshes will keep failing. Check for leading or trailing spaces and line breaks, and make sure a messaging app hasn't cut off parameters after &.

A 403 doesn't necessarily mean your plan has expired; it can also result from access policies, header restrictions, or a security challenge page. A 200 doesn't guarantee a valid subscription either: login pages, verification pages, and error messages can all return a successful status. Check the response body, not just whether the URL opens in a browser.

Use curl to distinguish HTTP errors from connection failures

Run this command in Bash with curl installed. It reads the URL without displaying it, so it won't be written directly to shell history. The output file is for local inspection only and may contain node credentials; delete it when you're done. The 20-second limit applies to this diagnostic command, not to the client's default settings.

umask 077
read -r -s -p 'Subscription URL: ' SUB_URL
printf '\n'
curl --noproxy '*' --location \
  --connect-timeout 10 --max-time 20 \
  --output subscription-response.txt \
  --write-out 'HTTP=%{http_code}\nTYPE=%{content_type}\n' \
  "$SUB_URL"

HTTP=000 is not a server status code. It usually means no valid HTTP response was received; use curl's error message to diagnose DNS, connection, or certificate problems. Hidden input does not fully protect a secret: while the command is running, the URL may still appear in local process arguments. Don't run it on an untrusted shared host.

  • If the response is 301 or 302, make sure the final destination isn't a login page; --location follows redirects.
  • For 429, follow Retry-After first. Don't try to fix it by refreshing every minute.
  • If you see a certificate error, check the system clock and certificate chain. Don't disable TLS verification as a permanent fix.

Blocked connections and updates that bypass the proxy

A subscription URL working in your browser doesn't mean the client's updater can reach it. The browser may use the system proxy while the updater connects directly. Conversely, with TUN or a transparent gateway enabled, network-layer interception may also capture requests marked as direct. The comparison below only shows whether curl explicitly uses an HTTP proxy; the command alone can't prove that traffic bypasses TUN entirely.

Compare requests using the local proxy port

First, check which HTTP or mixed port the client is listening on. The example uses 127.0.0.1:7890 and only works if a service is listening on that port. If your configuration has mixed-port: 7897, change the port in the command to 7897.

curl --noproxy '' --proxy http://127.0.0.1:7890 \
  --location --connect-timeout 10 --max-time 20 \
  --output subscription-via-proxy.txt \
  --write-out 'HTTP=%{http_code}\nTYPE=%{content_type}\n' \
  "$SUB_URL"

unset SUB_URL

If the explicit proxy request succeeds while the earlier request failed, investigate the network route first. That still doesn't prove the GUI client uses the same route. Enable subscription-update logs in the client, refresh once, and look for the matching request. Then check its proxy, policy group, and error details. Some clients use a downloader separate from the core, so a missing entry in the connections panel doesn't prove that no request was made.

Avoid circular dependencies when updating subscriptions

  • If only nodes from a subscription can reach its domain, and all those nodes are down, enabling “Use proxy for updates” won't restore connectivity. You'll need a working fallback route or an accessible endpoint from your provider.
  • If the logs show the subscription domain matching DIRECT and you've confirmed direct access fails, adjust the rules to suit your network requirements, then verify which rule actually matches.
  • If the error indicates a DNS lookup failure, first check the subscription hostname and DNS logs. Don't change DNS, TUN, rules, and ports all at once, or you won't know which change fixed the problem.
  • If the update fails only on a particular Wi-Fi network, try once over mobile data to compare. This can help isolate network differences; reinstalling the client shouldn't be your first step.

Incompatible format: a successful download still needs validation

A subscription endpoint may return a full YAML configuration, a YAML file containing only proxies, an encoded list of share links, or a format specific to another client. Whether a GUI client converts the response automatically depends on its implementation. mihomo HTTP proxy providers and full-configuration loaders also expect different inputs, so don't use the same response interchangeably.

Check the structure of the response

  1. Open the response file in a local text editor. If it starts with <!doctype html> or contains login-page text, the problem is still with downloading or authentication, not YAML indentation.
  2. A full configuration typically includes fields such as proxies, proxy-groups, and rules. A native YAML proxy-provider file typically uses proxies: to define its proxy list. The right combination of fields depends on how the file will be used.
  3. Check that the names referenced in proxy-groups and rules exist. A proxy list may download successfully, but missing policy-group references can still make the configuration unusable.
  4. If your provider offers separate Clash and Clash Meta formats, choose the one that matches your core. Older Clash cores may not support newer mihomo fields or protocols.

If mihomo is installed locally, validate a copy of the full configuration for syntax and configuration errors. This example assumes the file is saved as config.yaml in the current directory. A proxy-provider file can't be validated as a full configuration. If the configuration references external files, make sure the working directory and dependency paths are correct.

mihomo -v
mihomo -t -d . -f ./config.yaml

Use -v to record the actual core version and check which fields it supports. Passing -t doesn't guarantee that every proxy will connect. Save the exact error and core version before investigating; don't force a load by deleting every unfamiliar field. If you need to convert the format, use a trusted, controlled process and never submit a full subscription token to an unknown conversion site.

Where to set the client's auto-update interval

Auto-update settings are part of the client interface, and their labels and locations may vary by version. Note the client version from the About page, then open the target subscription's edit window. Don't confuse the node latency test interval with the subscription download schedule, or assume that “Update all subscriptions” enables scheduled updates.

ClientWhere to find the settingWhat to check
Clash Verge Rev“Subscriptions” → target subscription card menu or right-click → “Edit”Update interval; proxy-update option, if available in your version
Clash for Windows (legacy versions)“Profiles” → right-click the target remote profile → “Settings”Update interval; proxy download option and units shown in the interface
Clash for Android (legacy versions)“Profiles” → edit button for the target remote profileAuto-update and interval; network-related options in global settings
mihomo CLIproxy-providers in the configuration fileinterval and proxy

In Clash Verge Rev, start by looking for fields such as “Update interval” and “Use proxy” in the subscription editor. If your version puts update methods in the card menu, use the relevant proxy-update action there. A successful manual update through a proxy doesn't necessarily mean scheduled updates will use the same mode; reopen the settings to confirm the saved value.

Clash for Windows and Clash for Android are discontinued legacy clients, and their interfaces vary across existing versions. If your version doesn't have a proxy-update option, don't follow menu instructions for another client. Use logs to confirm the actual request route, or switch to a maintained client that supports your configuration.

Enter the interval in the units shown

A good starting point is 6 or 12 hours, adjusted to your provider's limits. If the interface says “minutes,” enter 360 for 6 hours or 720 for 12. If it says “hours,” enter 6 or 12. Don't infer the unit from the number field alone. After saving, update manually and check that “Last updated” changes.

On mobile, background execution, battery optimization, and system sleep can also affect scheduled tasks. Updates usually can't be guaranteed to run to the second while the screen is locked. Desktop clients also generally stop running scheduled tasks after you quit the app. If updates only happen after reopening the app, investigate its lifecycle before shortening the interval.

mihomo interval and proxy settings

For HTTP-type proxy-providers, interval is measured in seconds. For example, 21600 is 6 hours, 43200 is 12 hours, and 86400 is 24 hours. This is the proxy-provider download interval, not the auto-refresh setting for a full remote configuration.

In mihomo versions that support the relevant field, a provider's proxy specifies the outbound proxy or policy group used for downloads. The fields below are intended to be merged into an existing HTTP provider, not used as a complete configuration. Keep the existing url, path, and provider name. PROXY must match an outbound name already defined in the configuration and currently available.

interval: 21600
proxy: PROXY
health-check:
  enable: true
  url: https://www.gstatic.com/generate_204
  interval: 600

Here, health-check.interval: 600 means a health check runs every 600 seconds; it does not mean the subscription downloads every 10 minutes. Choose a health-check URL based on network reachability and your needs. The example URL is for connectivity testing, not a subscription URL.

Running mihomo from the command line won't make it periodically download the entire configuration just because you add interval at the top level. To refresh a full configuration, use a controlled external task to download, validate, back up, and reload it, keeping the original file if anything fails. Never overwrite an active configuration directly with a network response.

No changes after updating? Check these six things

  1. Check which subscription you updated. Verify the card name and the source of its URL. You may have updated a backup subscription while still using a different configuration.
  2. Check the time and content. A changed update time only shows that the client recorded an update attempt; the server may have returned identical content. An unchanged proxy count alone doesn't prove the update failed.
  3. Check that the new configuration is loaded. Some clients separate downloading from activation, so you may need to select the configuration or check the reload logs.
  4. Check where the proxy list comes from. If a policy group only references fixed local proxies, new proxies from a remote provider may not appear in that group. Check use and the provider name.
  5. Check filters. Region filters, regular expressions, or exclusion rules may hide new proxies. First check the provider's raw proxy count.
  6. Check that scheduled updates are still running. After restarting the client, verify that the update interval was saved, then check the timestamp after the next scheduled run.

Finally, delete any response files saved during troubleshooting so they don't remain in a synced directory or shared folder. If you still need to report the issue to a maintainer, provide the client and core versions, error time, HTTP status code, and a redacted copy of the error. Never attach subscription tokens, proxy passwords, or the full response in a public report.

rm -f subscription-response.txt subscription-via-proxy.txt

Recommended order: confirm the URL is valid → compare request routes → inspect the response format → validate configuration loading → set a sensible update interval. Auto-refresh can reduce manual work, but it can't fix a revoked token, an incompatible format, or an unreachable download route.