FAILURE LAYERS

First distinguish download, conversion, and config loading failures

A “subscription failure” is not a single problem. For a client to retrieve a config from a subscription URL and apply it, the process typically passes through network requests, server responses, content detection, YAML parsing, field validation, and core loading. Different stages may produce similar messages, but they require completely different fixes. Repeatedly clicking Update usually just repeats the same error.

The first category is download failure. The client did not receive a usable response. Common symptoms include request timeouts, reset connections, DNS resolution failures, HTTP 401, 403, 404, 429, or 5xx responses. YAML parsing has not started yet, so changing indentation in the local config will not help.

The second category is unexpected response content. The request returns a successful status, but the body may be a login page, an access verification page, an expired-plan notice, a JSON error object, or plain text containing only node URIs. Opening the URL in a browser only proves that the browser received a response; it does not prove that the response is a Clash config the current client can load.

The third category is syntax or field parsing failure. The server did return YAML, but its indentation, colons, quotes, list nesting, or character encoding may be invalid. The config may also use fields unknown to the current core. Logs commonly contain keywords such as YAML, unmarshal, decode, field, proxy, or rule.

The fourth category is unusable after loading. The subscription appears in the config list and node names are visible, but enabling the config fails or connections do not work afterward. This is often caused by missing proxy groups, invalid rule references, incomplete proxy protocol parameters, conflicting DNS settings, or core-version differences. Do not continue treating it as a URL access problem.

URL STATUS

Check the subscription link and request conditions

Subscription URLs usually contain query parameters that identify an account or authorization scope. Dropping parameters after the question mark, truncating a delimiter, or introducing a line break while copying can make the server return an error. Re-copy the complete URL from the provider’s subscription management page. Do not assemble it by hand or keep using a partially selected link from a chat message.

Make sure the URL was not truncated or escaped

  • Check that the URL starts with http:// or https://, and that the domain and path are complete.
  • Confirm that the query parameters are still present, especially the question mark, equals signs, delimiters, and the final characters of parameter values.
  • When scanning a QR code or copying across devices, check for spaces, non-ASCII punctuation, or line breaks inserted in the middle of the URL.
  • If the URL is inside a YAML string, enclose it in quotes when it contains special characters so it is not treated as a comment or syntax marker.

Use the HTTP status to choose a direction

401 / 403
The authorization parameters are invalid, the request conditions are not met, or the server has denied access. Obtain a new subscription URL and check the account status and provider-side restrictions.
404 / 410
The path does not exist or the resource has been revoked. The provider may have replaced the old URL; refreshing the local cache will not restore it.
429
Too many updates were requested in a short period. Stop refreshing repeatedly, wait for the rate-limit window to end, and then run one more test.
5xx
The server cannot complete the request temporarily. Record the time and status code, then try again later or contact the subscription provider.

For timeouts or DNS resolution failures, also check the underlying network connection. Temporarily disable the system proxy and TUN, then access the subscription domain to determine whether updates incorrectly depend on a proxy that has not started yet. Some clients let you choose DIRECT or a proxy policy for config updates. If the subscription domain is unreachable directly on the current network, define the update traffic path explicitly to avoid a loop: the config must be loaded to reach the subscription, but the subscription must be reached to load the config.

RESPONSE BODY

Verify that the response body is actually a Clash config

HTTP 200 only means that the server completed a request; it does not mean the body has the right format. A common example is a subscription URL redirecting to a login or access verification page, leaving the client with HTML. The parser may then fail near <!doctype html>, <html>, or another tag on the first line.

A complete Clash config is usually YAML text. Common top-level fields include proxies, proxy-groups, rules, dns, proxy-providers, and rule-providers. The combination varies by use case, and no file needs to contain every field, but the body should not be a webpage, an error message, or an account information page.

proxies:
  - name: "Example Node"
    type: ss
    server: example.invalid
    port: 443
    cipher: aes-128-gcm
    password: "example-password"

proxy-groups:
  - name: "Node selection"
    type: select
    proxies:
      - "Example Node"
      - DIRECT

rules:
  - MATCH,Node selection

Another common response is a Base64-encoded collection of node URIs. After decoding, it may consist of entries such as ss://, trojan://, and vmess://. This is not complete Clash YAML. Some graphical clients run a conversion step during import, while others accept only complete configs, so the same URL can produce different results in different apps. On the provider’s subscription page, choose an output explicitly labeled Clash, Mihomo, or a compatible format instead of loading an arbitrary universal subscription as a YAML file.

Also check for redirects. A subscription URL may first return 301 or 302 before sending you to the actual download URL. If the client blocks cross-origin redirects, the target domain has a certificate problem, or authorization parameters are lost after the redirect, browser and client results may differ. If the logs mention redirect, certificate, TLS, or hostname together, check the redirect target and system clock first rather than editing proxy-node fields.

The response character encoding should generally be UTF-8. Unexpected invisible characters at the start of the file, or a body decoded using the wrong encoding, can prevent the first field from being recognized. Use a trusted local text editor to inspect the encoding, save the file as UTF-8, and test it as a local config. If the local file loads but the remote subscription does not, the problem is usually in the server response headers, body encoding, or download path.

YAML PARSING

Check YAML indentation, quotes, and list structure one item at a time

YAML uses indentation to express hierarchy, so the number of spaces and field positions directly change the data structure. Clash configs typically use two spaces per indentation level. YAML permits other consistent widths, but standardizing on two spaces is easiest to read and reduces nesting mistakes when copying snippets. Tabs should not be used for indentation.

The most common syntax errors

  1. Incorrect list indentation: - name must appear under the corresponding list field. If it is aligned with proxies:, the parser treats it as a new root-level structure and reports an error.
  2. Missing space after a colon: Fields are usually written as port: 443, not port:443. The latter may be interpreted as a plain string.
  3. Special characters in a name without quotes: If a node or proxy-group name contains a colon, hash, square brackets, curly braces, or a leading asterisk, enclose it in double quotes.
  4. A comment truncates the value: An unquoted hash starts a comment. If a password or name contains a hash, everything after it may be ignored.
  5. Duplicate keys or the wrong type: Declaring rules twice at the same level, or writing a field that requires a list as a single string, can fail during parsing or field validation.

The problem with the following snippet is that the entries under proxies are missing one indentation level, and the name referenced by the proxy group does not match the actual node name:

proxies:
- name: "Hong Kong node"
  type: ss

proxy-groups:
  - name: "Node selection"
    type: select
    proxies:
      - "Hong Kong node 01"

Fixing indentation is only the first step. Node names in proxy groups, policy names in rules, and provider reference names must match their definitions exactly, including spaces, capitalization, and full-width characters. Successful YAML parsing does not mean every reference is valid; reference errors often appear only when the core loads the config.

If the log provides a line and column number, inspect the reported line first, then check the nearest parent field above it. The position identified by the parser is sometimes where parsing became impossible, while the real error is on the previous line—for example, an unclosed quote, a missing array bracket, or an indentation level that ended too early. Do not simply delete the reported line, or you may end up with a syntactically valid but incomplete config.

CORE COMPATIBILITY

Check field compatibility between Clash and Mihomo

Even syntactically valid configs can fail to load because core capabilities differ. Traditional Clash, its successor implementation Clash Meta, Mihomo, and the core versions bundled with different graphical clients do not guarantee support for exactly the same protocol parameters and extension fields. If a provider generates a newer Mihomo-format config while the client still uses an older core, you may see unknown fields, unsupported proxy types, or parameters that cannot be unmarshaled.

During troubleshooting, check the actual core name and version in the client’s About or Core section, or at the beginning of its logs. Do not infer it solely from the graphical client’s name. Some clients allow core switching, yet continue to run updates with an older core; others update the app without updating the bundled core files.

Areas prone to version differences

  • Proxy protocol fields: New protocol types, transport-layer parameters, fingerprint settings, and UDP options may require a newer Mihomo version.
  • TUN settings: Different versions may expect different values for network stacks, auto routes, interface detection, and DNS hijacking fields. The presence of a field does not mean the current platform has the required permissions.
  • Enhanced DNS modes: The structures for fake-ip, redir-host, nameserver policy, and fallback must have the correct nesting and types. Older config examples may not apply to the current core.
  • Rule sets and providers: The remote URLs, update intervals, file paths, and behavior values for rule-providers and proxy-providers must match the format supported by the core.
  • Sniffing and geographic data: The behavior of sniffer, GEOSITE, GEOIP, and geodata features varies with the core implementation and the state of the data files.

When logs show field not found, unsupported proxy type, invalid value, or similar messages, consult the documentation for the current core and the relevant field. Temporarily removing an unknown field can confirm the source of the failure, but do not keep it removed without understanding the impact. For example, deleting TUN route fields may let the config load while preventing system traffic from entering the core; removing DNS settings may also change the domain-resolution path.

If the subscription service offers both Clash and Mihomo formats, clients using the Mihomo core should generally select the config explicitly intended for Mihomo. Conversely, older Clash cores should use the basic fields they support. Repeatedly changing the file extension will not solve compatibility issues; an extension does not convert the config structure.

CACHE AND UPDATE

Clear failed caches and confirm that the config actually updated

Many graphical clients download a remote subscription to a local file and then load it from cache. When an update fails, the client may continue using the last successful version, or it may write a temporary file containing only an error page. Therefore, seeing the old node list does not prove that the latest update succeeded, and a changed update time alone does not prove that the core accepted the new config.

Record the name and update time of the currently working config, and export any necessary local overrides. Then check the client logs to confirm that the update includes request completion, file writing, config validation, and core reload. If you see download completed but no reload or successful config switch, the process may have stopped during validation.

Safe cache-clearing sequence

  1. Stop automatic updates to prevent files from being overwritten or rate limits from being triggered during troubleshooting.
  2. Keep a local copy of the most recent config that worked so you can restore basic connectivity.
  3. Delete the failed subscription entry from the client, then add it again using a freshly copied complete URL.
  4. Exit the client completely and restart it, confirming that its background core process has also ended.
  5. Run one manual update and immediately check the HTTP status, file path, and first error in the logs.
  6. After the update succeeds, re-enable automatic updates and set a reasonable interval.

If the client supports overrides, merges, or preprocessing, temporarily disable those features as well. If the raw subscription parses but the merged result fails, the problem is in a local override file. Common causes include duplicate proxy groups created by an override, rules pointing to deleted groups, a list being replaced with an object, or new fields being written for an older core.

The config storage path can also cause misleading results. Insufficient permissions, unsupported characters in the path, low disk space, or security software blocking writes can let the client download successfully but prevent it from replacing the old file. Logs often contain write, permission, rename, or file in use. Fix the file-writing conditions instead of continuing to edit the remote subscription.

DIAGNOSTIC ORDER

Follow a fixed order when checking a failed subscription import

Efficient troubleshooting means validating one layer at a time and recording the result of each step. The sequence below applies to related problems such as a broken subscription URL, config parsing failure, or a config that cannot be enabled after updating. It also reduces interference between network, format, and client problems.

  1. Verify the underlying network: Pause the system proxy or TUN, confirm that ordinary connectivity and DNS work, then test whether the subscription domain can establish a connection.
  2. Obtain a fresh URL: Copy the complete link from the subscription management page, ruling out truncation, expiration, and manual edits.
  3. Record the request result: Check the HTTP status, redirects, TLS messages, and response type. Do not use “it opens in a browser” as the only test.
  4. Identify the body format: Confirm whether the response is complete Clash YAML, a provider file, or a URI collection, then choose the matching import method.
  5. Check the YAML: Use the reported line to inspect indentation, quotes, colons, lists, and reference names, starting with a minimal config that can load.
  6. Check the core version: Confirm whether the client is actually using Clash or Mihomo, and verify that the reported field is supported by the current version.
  7. Disable local overrides: Test the raw subscription first, then restore rule merges, scripts, DNS, and TUN changes one at a time.
  8. Handle the cache: Keep a working copy, add the subscription again, and confirm that download, validation, writing, and core reload all complete.
  9. Verify runtime behavior: Check that proxy groups are complete, rules match, and DNS returns the expected results before testing an actual connection.

When contacting the subscription provider, include the time of the incident, client name, actual core and version, HTTP status, several lines before and after the error in the logs, and the beginning of the response with authorization details redacted. Do not send only a screenshot saying “import failed.” Clear evidence quickly shows whether the problem lies in subscription generation, server access control, format conversion, or client compatibility.

If the same local YAML loads in the current core but importing the remote URL fails, focus on the download request, redirects, response encoding, and cache writes. If multiple clients can download the body but all fail on the same field, the provider-generated config is more likely to have a syntax or compatibility problem. If only one device fails, return to that device’s system clock, network, certificates, file permissions, and client core version.

After fixing the issue, keep a recent working config and record its subscription format and supported core. If an update fails later, you can quickly distinguish a change in the remote subscription from a change in the local runtime environment instead of losing every troubleshooting option when offline.