Clash Subscription Update Failed? Fix Config Parsing Errors
Troubleshoot expired subscription links, invalid responses, YAML indentation, and unsupported fields. Follow the error logs from request to config load.
First, pinpoint the stage: request, parsing, or config loading
“Subscription update failed” is a catch-all message from the client; it doesn’t necessarily mean the subscription URL is invalid. An update typically involves requesting the URL, receiving a response, parsing the config, applying overrides, and loading it into the core. A full config may also reference remote proxy and rule providers, each with its own download process.
Keep the current working config while troubleshooting. Don’t delete all subscriptions or repeatedly switch between system proxy, TUN mode, and DNS settings. Change one thing at a time, and note the update time and related log entries so you can identify where the failure occurs.
- Back up: Export the current config from the “Subscription” or “Profiles” page. Save local overrides, scripts, and rules separately. Exported files may contain proxy credentials, so store them in a restricted-access folder.
- Reproduce: Open “Logs,” temporarily set the level to
info, and run one manual update. Note errors around that time. Switch todebugtemporarily only if you need more detail. - Classify: First look for an HTTP status code or network error, then check the YAML line number, and finally review errors related to proxy groups, rules, or fields.
- Record: Note the client version and the actual core name and version. The client version is not the mihomo version; run
mihomo -vto check the version of that executable.
Subscription request failed: check the URL and HTTP response first
Status codes and what to do next
Copy the full subscription URL again from your provider’s account page; don’t assemble the parameters by hand. The token, query parameters, and path can all affect the result. Line breaks added by messaging apps, spaces included during copying, or accidentally changing & to & can point the URL to a different resource.
| Response or log entry | Common meaning | What to check |
|---|---|---|
401 / 403 | Authentication failed, token expired, or access denied by policy | Check your account status and get a fresh URL. Then check device and client restrictions; a 403 may also come from a gateway or security page. |
404 / 410 | Path not found or resource removed | Get a new URL from your account page; don’t just change the domain in the old one. |
429 | Request rate limited | Stop retrying. Wait before trying again, following Retry-After or the server’s instructions. |
500 / 502 / 503 | Server or upstream error | Keep the old config, try again later, and check your provider’s service announcements. |
200 but parsing failed | A response was received, but it may not contain a config | Check whether the body is a login page, verification page, error JSON, or a different subscription format |
Opening in a browser doesn’t prove the client can update
A browser may have a login cookie, pass a web verification check, or use a different proxy route through an extension. The client’s subscription request usually has none of these. So a page loading successfully doesn’t prove the subscription endpoint is accessible to the client. For 301 or 302 responses, check that the redirect destination is still the subscription resource—not a login page.
To inspect the raw response on macOS or Linux, run the command below in Bash. It won’t put the URL directly in shell history or follow redirects automatically. Check the response headers first, then decide whether to visit the redirect target. This command tests a direct connection only; not every client fetches subscriptions directly.
read -r -s -p 'Subscription URL: ' SUB_URL
printf '\n'
curl --noproxy '*' \
--connect-timeout 10 \
--max-time 30 \
--dump-header response.headers \
--output response.body \
--write-out 'HTTP %{http_code}\n' \
"$SUB_URL"
unset SUB_URL
Both response.headers and response.body may contain sensitive information. Inspect them locally and delete them when you’re done. Don’t paste your subscription URL into a public converter or send the full response to a public online YAML validator.
Network and TLS errors: test direct and proxied connections separately
If there’s no HTTP response, troubleshoot the network connection first. System proxy settings affect only requests that honor them; a client may use its own downloader for subscriptions. TUN mode can change how some traffic is routed, but it can’t fix an expired token, invalid response format, or YAML syntax error.
no such host: DNS lookup failed. Check the subscription domain spelling, then review system DNS settings and the client’s DNS logs. Don’t mistake a DNS failure for a proxy protocol error.connection refused: The destination actively refused the connection. If the log shows127.0.0.1:7890, first check that a local proxy is listening on that port instead of immediately replacing the subscription.i/o timeout,context deadline exceeded: The connection, TLS handshake, or response read timed out. Try the client’s direct update and proxy update options separately, once each, and record the results.x509, expired certificate, or hostname mismatch: Check the system date, time synchronization, subscription domain, and any HTTPS inspection software on the network. Don’t hide the problem by disabling certificate verification.
If updates require a proxy but the current subscription can no longer load, you may get stuck in a startup dependency: without a working proxy, you can’t download a replacement config. Switch to a previously saved working config and update through a proxy, or use an accessible direct endpoint if your provider offers one. Keeping the old config is more useful for recovery than repeatedly clearing client data.
Invalid response format: distinguish a full config from a proxy list
HTTP 200 means the request succeeded; it doesn’t mean the response works with the import option you’re using. Inspect the beginning of the response and its top-level fields in a local text editor, then compare them with the format specified by your provider. Don’t rely on the file extension alone.
| Response characteristics | Possible content | What to do |
|---|---|---|
<!DOCTYPE html> or <html | Login page, verification page, or web error message | Get the actual subscription endpoint; don’t save the webpage as YAML and import it |
| A long string of encoded text or one protocol URL per line | A proxy subscription intended for another client | On your account page, select Clash or the mihomo-compatible output specified by your provider |
Only a proxies: list | Possibly a proxy-list file | Check whether it should be referenced by proxy-providers rather than enabled directly as a full config |
Contains fields such as proxy-groups: or rules: | Possibly a full config | Continue checking syntax, references, and core compatibility; the presence of these fields alone doesn’t mean the config will work |
If the main config loads but the failed URL in the logs belongs to proxy-providers or rule-providers, the issue is with a referenced resource, not necessarily the main subscription. Proxy lists and rule lists also have different structures. Check the relevant provider’s url, format, and behavior against the actual response so a rule list isn’t parsed as a proxy list.
YAML parse errors: check indentation and data types around the reported line
Errors such as yaml: line …, did not find expected key, and cannot unmarshal usually point to a structural or data type issue. The reported line is often where the parser detected the problem, but the actual mistake may be on the previous line—for example, an unclosed quote, incorrect list indentation, or a missing space after a colon.
Four things to check first
- Indentation: Use spaces consistently, never tabs. Two spaces per level is common practice, not a YAML requirement; fields at the same level must line up.
- Punctuation: Use a standard colon after each key and a space between the key and value. Don’t paste full-width colons or curly quotes into config syntax.
- Data types: Ports are usually integers, such as
7890; Boolean values aretrueorfalse; list items start with-. Writing an entire list as a string can cause a type error. - Names and special characters: Quote names containing sequences such as
:or#correctly. When a proxy group references a name, its spaces, capitalization, and symbols must match exactly.
The direct-connection config below is for isolating the issue and contains no subscription proxies. It only checks whether the local core can read basic YAML; it doesn’t test proxy connectivity. If port 7890 is already in use, stop the process using it or choose a free port in a test copy.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
rules:
- MATCH,DIRECT
Save the config as UTF-8 text named profile.yaml. To test it with mihomo, use the command below. In Windows PowerShell, if the executable is in the current directory, run .\mihomo.exe -t -f .\profile.yaml.
mihomo -v
mihomo -t -f ./profile.yaml
For the most relevant result, test with the same core and working directory the client actually uses. Remote providers and relative paths can also make the test depend on network access, cache, and file locations. A passing test only means this config check found no blocking issue; it doesn’t confirm that all proxies, DNS, or rule downloads work.
Syntax passes but the config won’t load: check the core, overrides, and references
The client’s name doesn’t tell you whether its core supports the config
Legacy Clash and Clash Meta (now called mihomo) support different features. Support for protocols, transport options, and rule fields also varies by version. For unsupported proxy type, first check the specific proxy type and the core actually running; renaming the file to .yaml won’t add protocol support.
How unknown fields are handled depends on the core version and where they appear: some are ignored, while others cause errors. So a “successful import” doesn’t prove that new fields took effect. Prefer the compatibility output specified by your provider, then consult the core’s release notes before updating. Don’t blindly delete fields you don’t recognize.
Check dependencies based on the error
proxy … not found: Check the target names referenced by proxy groups or rules. A subscription update may rename a proxy while a local override still refers to its old name, leaving a broken reference.- Provider not found: Check that the
use:reference matches a key underproxy-providers, and make sure the merge process hasn’t overwritten the entire provider definition. - Rule target doesn’t exist: Check the policy name at the end of the rule against the proxy group names. A referenced group must exist with the exact same name; a similar name isn’t enough.
address already in use: This is usually a runtime port conflict, not a subscription format error. Check whether the mixed port, DNS listener, or controller port is already in use by another process.
If the downloaded raw config passes a test but the client reports an error after enabling it, focus on “Overrides,” “Merge,” or “Scripts.” Export them, temporarily disable them, and test the unmodified config; then restore them one at a time. In particular, check for scripts that rename proxies, replace proxy-groups, or add rules targeting nonexistent groups.
Validation checklist after fixing the update
Once the error is gone, run a complete validation. “Update successful” alone may miss failed provider downloads or empty proxy groups. A webpage loading successfully may only mean its traffic matched a direct-connection rule.
- Confirm the subscription’s last-updated time changed, then check that the proxy count, groups, and rules look as expected.
- Enable the target config and review logs for the same time period. Check for new config load errors or provider update failures.
- On the “Connections” page, make a request to the destination you want to test. Check the matched rule, outbound policy, and proxy name to confirm the route actually used.
- Re-enable any overrides or scripts you temporarily disabled, validating after each one. When you’re done, restore the usual log level.
When reporting an issue to a client maintainer or subscription provider, include the client and core versions, operating system, update time, HTTP status code, and the complete error line with sensitive details removed. Keep relevant indentation and references in config snippets, but remove subscription tokens, passwords, private keys, and proxy server addresses. If the issue began after an upgrade, include the versions from before and after it.
A good troubleshooting order is: confirm the request reached the server, check that the response is in the expected format, validate YAML and core compatibility, then inspect overrides and the runtime environment. Investigate one layer at a time; this is usually more effective than changing ports, DNS, and TUN settings all at once. For help setting up and configuring a client, see the client guides; for terminology and common questions, see the FAQ.