First, distinguish subscription downloads, config parsing, and core loading

An “update failed” message doesn’t necessarily mean your nodes are down. A subscription update usually has three steps: the client requests the subscription URL, parses the returned text, then passes the resulting config to the core for validation or loading. A failure at any step can trigger an error in the interface. Start by saving the full error message instead of repeatedly clicking Update.

Desktop clients usually have an update option under Subscriptions or Profiles, with details in the Logs view; labels vary by client version. Note the client and core names and versions, when the failure occurred, and whether the update was manual or scheduled. Clash and Clash Meta (now called mihomo) don’t support exactly the same config features, so the app name alone isn’t enough to determine compatibility.

Typical messageCheck this stage firstNext step
no such hostDNS lookupCheck the subscription hostname and DNS results
timeout、connection refusedConnecting or waiting for a responseCheck the network path, proxy port, and service status
HTTP 401、403、429Server responseCheck authorization, access restrictions, and request frequency
yaml: line 12Text parsingInspect the response body, especially around line 12
proxy not foundConfig reference validationCheck names referenced by proxy groups, nodes, and rules

Expired subscription links, authorization failures, and server restrictions

Make sure you copied the subscription URL, not a management page

Subscription URLs often include a token, query parameters, or a dedicated path. An account dashboard URL, login page, or QR-code image URL won’t work as a subscription. Copy the Clash or mihomo link from your provider’s dashboard, then check for extra spaces, line breaks, or curly quotes at either end. If you copied it from a webpage’s source, note that & may be an HTML-escaped separator, not part of the original URL.

  • 401: Usually an authorization issue. Check whether the token was reset or the account expired; refer to your provider for the exact meaning.
  • 403: May indicate an access policy, source IP, User-Agent, or account permission restriction. Don’t assume the link has expired.
  • 404: Check whether the endpoint path changed, the URL was truncated, or the old subscription was revoked.
  • 429: Stop retrying. Wait for the Retry-After value in the response or follow your provider’s guidance. Scheduled refreshes across multiple devices can also trigger rate limits.
  • 502, 503, 504: These usually point to a server or gateway issue. Note when it happened and try again later.

A subscription opening in your browser doesn’t mean the client received the same content

Your browser may send a login cookie or show content only after a web-based verification step; clients usually don’t share those sessions. Even with an HTTP 200 status, the response body could be a login page, CAPTCHA, or “traffic quota exceeded” message. Check the actual response body, not just the status code. Never paste a subscription URL into a public online checker: its token may be enough to access your account’s node details.

Local network blocks: check DNS, TLS, and the proxy path

The network path used to download a subscription may differ from the one used to connect to nodes. Some clients download configs through the GUI, while others delegate the request to a separate component. System proxy settings, TUN mode, and the client’s “update through proxy” option can all affect the result. Browser access only confirms that the browser’s current network path works.

  1. Check the system clock. A badly wrong date, time zone, or clock can cause TLS certificate validation to fail. Enable automatic time sync, then try once more.
  2. Check DNS resolution. On Windows, run nslookup followed by the subscription hostname; on macOS or Linux, use dig. Enter only the hostname, not the token path.
  3. Try another network. Switch to a mobile hotspot using the same client and config. If it works on the hotspot but not your current network, check the router’s DNS, corporate gateway, captive portal, or firewall first.
  4. Check the local proxy listener. If the update relies on 127.0.0.1:7890, make sure the core is running and listening on that port. Port 7890 is just a common example; use the configured mixed-port or HTTP proxy port.
  5. Change one thing at a time. Test updating directly, then through a working proxy, and record the results. Don’t change DNS, enable TUN, and edit rules all at once, or you won’t know what fixed it.

connection refused often means nothing is listening on the destination port. i/o timeout can occur while connecting or waiting for data. Check the destination address in the logs to tell which case applies. If it’s a local proxy port, fix the local service first; if it’s the subscription server, investigate the external connection.

User-Agent restrictions and subscription output formats

User-Agent is an HTTP request header. Subscription services may use it to identify the client and return a full Clash config, a node list only, or another format. It’s not unusual for a browser and a client to receive different content from the same URL. Some services also require the target format to be specified in the link parameters, so changing the request header alone may not help.

Check the request source, not just the YAML

If the client has a subscription User-Agent setting, use the value documented by your provider and note the original. Don’t impersonate an unrelated client at random; the provider may return incompatible fields. The initial full-config download happens before YAML parsing, so adding a request-header field to that YAML usually can’t change the request that downloads it.

In versions that support the relevant fields, mihomo’s proxy-providers can set request parameters for provider downloads. That’s a core-level request to fetch node providers, not the same as updating an entire subscription through a GUI client. When an update fails, first check whether the log refers to a config subscription or a provider.

Identify the type of data in the response

Response contentWhere to use itCommon mistake
YAML containing proxies, proxy-groups, and rulesImport as a full configStill check whether the core supports its node types and fields
YAML that usually contains only proxiesNode providerTreating it as a full config leaves out groups and routing rules
A payload rule setRule providerAdding it to the node subscription field
Base64 text or multiline protocol linksAn import or conversion flow that supports the formatPassing it straight to a YAML config parser
An HTML page or JSON error objectNot a loadable Clash configMistaking a server message for an indentation error

If you need to convert formats, prefer an export option supported by your subscription provider or a trusted local tool. A third-party online converter can see your original URL and node credentials; treat it as a service with access to your account, not as a basic text editor.

YAML parse errors: inspect the response before the line number

If you see mapping values are not allowed, did not find expected key, or cannot unmarshal, open the downloaded file in a local text editor first. If it starts with <!DOCTYPE html>, revisit authorization and network issues; changing YAML indentation won’t help.

Check indentation, data types, and references one by one

  • Indentation: Use spaces, not tabs, and keep indentation consistent at each level. The reported line may simply be where the parser gave up; the actual problem could be on the previous line.
  • Colons and quotes: Quote names that contain a colon followed by a space, for example name: "Hong Kong: 01". Don’t use curly quotation marks in place of YAML quotes.
  • Field types: Ports are usually numbers, and boolean values are usually true or false. Lists such as proxies and rules need the correct hyphenated structure.
  • Duplicate keys: Don’t define dns: or rules: twice at the same level. Parsers may handle duplicate keys differently; merge the sections, then validate the result.
  • Name references: Nodes referenced by proxy groups and proxy groups referenced by rules must exist, with matching names. If a subscription update renames a node, old manual references can break.

Use the following config only to test the local parsing and loading flow. All connections are direct; it contains no remote nodes. Save it as a separate test file and don’t overwrite an existing subscription:

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

proxies: []

proxy-groups:
  - name: "Select an exit"
    type: select
    proxies:
      - DIRECT

rules:
  - MATCH,Select an exit

If this example passes but the subscription doesn’t, the issue is more likely in the subscription content, merge script, or field compatibility. It doesn’t prove that the external subscription URL is reachable or test proxy node connectivity. If you see a port-in-use error, stop the existing instance or switch to an unused port before loading it again.

When using the mihomo command line, run the config check from a separate directory. subscription-test.yaml is the test file you just saved. If the config includes remote providers, the check may still depend on files or network access; it isn’t a pure YAML syntax check.

mihomo -t -f subscription-test.yaml

Core incompatibility, config merging, and failures after an update

A config that parses as YAML isn’t necessarily usable by the core. Subscription node protocols, transport options, or rule types may not be supported by your current core. For unsupported proxy type or an unknown rule type, first note the actual version shown in the client’s About screen or core information, then check the docs for that core. The app version and core version are separate.

Check the original, enhanced, and runtime configs separately

  1. Keep the original file downloaded from the subscription and check whether it validates with a compatible core.
  2. Temporarily disable any overrides, merges, or scripts associated with the config; the exact controls depend on the client’s config editor.
  3. If the original file works, restore local extensions one at a time and check whether they overwrite proxy-groups, rules, or provider names.
  4. If a provider is failing, check its own url, save path, response structure, and update logs. Don’t just refresh the top-level config.

Don’t delete every unknown field just to make the error go away. Some fields control protocol handshakes or transport behavior; removing them may let the config load while leaving nodes unable to connect. Instead, choose a target format your provider explicitly supports, or use a maintained client and core that can handle the config.

Verify the update and prepare a useful bug report

After applying a fix, run one manual update and check the update time, node count, and core loading logs. A normal node count is only a first check: select a node and visit a familiar site to confirm that the connection log shows the expected rule and outbound. A successful latency test doesn’t guarantee all traffic works; a rule error may still send specific domains through the wrong outbound.

  • Download succeeded: No HTTP, DNS, or TLS errors appear in the logs, and the response is the expected format rather than a webpage.
  • Parsing succeeded: No YAML line errors, field type errors, or missing references remain.
  • Loading succeeded: The active runtime config has switched to the updated content, and the core hasn’t reverted to or continued using the old config.
  • Connections work: Inspect a new connection and verify the matched rule and proxy group; don’t rely on a cached page alone.

Share enough details to troubleshoot, but protect your credentials

When reporting an issue to a client maintainer or subscription provider, include your operating system, client and core versions, the time of the error, HTTP status code, and relevant log excerpts. Describe the results of direct versus proxied updates and your current network versus a hotspot. Before sharing screenshots, hide the full subscription URL, tokens, node passwords, and account details. Hiding only the domain while leaving query parameters visible can still expose your credentials.

A reliable troubleshooting order is: verify the URL and authorization, inspect the response and network path, then check the format, YAML, and core compatibility, and finally review local overrides. Change one thing at a time and record the results. That makes it easier to identify exactly why a Clash subscription update failed than repeatedly reinstalling the client.