Subscription URLs, node links, and config files
“Subscription” can mean very different things: an HTTPS URL, a few node links starting with ss://, or a YAML file containing proxies:. To tell whether Clash can import it, focus not on the link’s length or the file extension, but on the response the client receives and whether its current core understands the fields.
A subscription URL is an entry point for fetching content; the subscription format is the structure of the returned data; and the proxy protocol defines how a node communicates with a server. These are not interchangeable. Renaming nodes.txt to config.yaml does not change the format, and Base64-encoding text does not add protocol support to a client.
- Subscription URL: Usually an HTTPS URL containing an account token. It is used to fetch updates, and the server determines what content it returns.
- Node share link: A protocol-specific URI representing a proxy node, such as
ss://,vmess://, ortrojan://. Each protocol encodes its fields differently. - Full config: May define proxy nodes, proxy groups, rules, DNS, listening ports, and external resources.
Base64 subscriptions: encoded collections of node links
A common subscription format puts multiple node share links on separate lines, then Base64-encodes the entire text. Decoding it reveals a list of URIs, not a complete config that Clash can load directly. Some services return unencoded link lists or other structures, such as JSON, so a long string of letters alone does not tell you what format it is.
Base64 does not encrypt data
For example, aGVsbG8= decodes to hello. Base64 simply represents bytes as text for easier transmission; it requires no key. Even if a subscription’s passwords, UUIDs, and server addresses are encoded, anyone who obtains the content may be able to decode them.
Standard Base64 commonly uses letters, digits, +, and /, and may end with =. The URL-safe variant uses - and _; some implementations omit padding. A decode error may come from the variant used or how line breaks are handled, so don’t assume the subscription has expired.
Decoding the outer layer is only the first step
Traditional vmess:// share links often store JSON in a Base64 payload; ss:// has its own conventions for encoding user information and specifying plugin parameters. Decoding the subscription and parsing an individual protocol link are separate steps. Repeatedly pressing a generic “decode” button is no substitute for a protocol parser.
Clash YAML: combining proxy nodes, groups, and rules
YAML is a data serialization language, not a Clash-specific format. A YAML file works as a config only if it follows the structure expected by the current core. A syntactically valid YAML document with ordinary content still cannot be imported as a Clash config.
| Field | Purpose | What to check |
|---|---|---|
proxies | Defines individual proxy nodes | Whether the core supports the proxy type and transport fields |
proxy-groups | Organizes strategies such as manual selection and automatic testing | Whether referenced node and group names exist |
rules | Determines the strategy used for connections, in order | Whether rule targets and the final fallback strategy are valid |
proxy-providers | Declares external proxy resources | Resource format, URL, and update status |
dns | Configures the core’s DNS resolution behavior | Upstream reachability and compatibility with traffic interception modes |
A config example for understanding the structure
This example uses mixed port 7890 and includes only a direct-connection strategy. It has no remote proxy nodes and cannot be used to test whether a proxy service works. It illustrates how lists, indentation, proxy group references, and fallback rules fit together. Port 7890 is used only for this example; clients do not all use that port.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
proxies: []
proxy-groups:
- name: "Proxy Selection"
type: select
proxies:
- DIRECT
rules:
- MATCH,Proxy Selection
Use spaces for YAML indentation; tabs cannot be used to show nesting. Quote passwords that contain special characters such as # or colons, and keep node names consistent. If the rule target in the example were changed to a nonexistent “Proxy Egress” group, config validation could still fail even with correct indentation.
Also distinguish a full config from a proxy provider resource. A common YAML node resource contains only a top-level proxies: field. It can be referenced by proxy-providers, but it is not a complete config with routing rules already set up. Some clients fill in proxy groups automatically; others do not, so don’t expect identical import results across clients.
Format compatibility and core compatibility are separate checks
The Clash client handles the interface, subscription management, and system integration; the core handles connections, parsing, and rule execution. Clash Meta continued development under the name mihomo, but “supports Clash configs” does not mean every core generation supports exactly the same fields.
For example, configs with VLESS, Hysteria2, or TUIC nodes require checking support in the target core and its specific version. Converting these nodes to YAML does not give an older Clash core support for those protocols. Even when a protocol is supported, Reality, transport, or TLS parameters may require a particular version.
- Check the input format first: Does the import screen accept a subscription URL, a full config file, or an individual node share link? “Import from clipboard” does not necessarily support every URI.
- Check the core next: Find the actual core in the client’s About page or core management screen; don’t rely on the app name alone.
- Then check the fields: Note the full config validation error and identify whether it points to a proxy type, transport parameter, or resource reference. Avoid repeatedly reinstalling the client.
In the common Clash for Android interface, remote configs are usually added via “Profiles” → “+” → “Import from URL.” After importing, select the profile and start the service. Other clients may put similar options under “Profiles” or “Subscriptions,” and button names can vary by version, so check the interface you’re using. If you have only a single node link, don’t assume pasting it into a “Config URL” field will import it.
Subscription conversion: parse nodes, then generate the target config
Subscription conversion is not a matter of changing a Base64 string’s file extension. A converter typically fetches the source content, identifies and parses each node, builds an internal representation, then generates node fields in the target format. If the target is a full Clash config, it may also apply a rules template, create proxy groups, configure DNS, or add automatic testing settings.
What conversion can preserve—and what it can’t
- Usually mappable: Server addresses, ports, passwords or UUIDs, and TLS and transport parameters with clear equivalents—provided the target core supports them.
- May not be preserved: Plugin options unsupported by the target format, protocol-specific parameters, client-specific extensions, and certificate settings with unclear origins.
- Needs to be rebuilt: Rules, DNS, nested proxy groups, and testing strategies. Node links usually don’t contain enough information to recreate these settings.
Converting a full YAML config to generic node links usually keeps only the nodes. Routing rules, DNS, and proxy group selection logic are not automatically embedded in each URI. So “YAML → link list → YAML” is not guaranteed to reproduce the original config, and this round trip is not a reliable backup method.
Credentials and online converters
If you give a subscription URL to an online conversion service, the service typically needs to access the source subscription—and can therefore see the URL’s token and the credentials in the returned nodes. HTTPS between your browser and the conversion page protects data in transit, but does not prevent the service from reading it.
Use a Clash- or mihomo-specific subscription from the provider whenever possible. If conversion is necessary, choose a tool whose operation you understand and, if practical, run it locally. Before sharing the converted result, inspect the full URL: the source subscription may be embedded in its query parameters. If you share it by mistake, reset the subscription token in the provider’s dashboard and check whether node credentials also need to be changed.
Import failures: troubleshoot the response, parsing, and connection in order
“Subscription imported successfully” and “node connected successfully” are different stages. Keep the original config while troubleshooting, and don’t change DNS, rules, ports, and TUN settings all at once. Change one thing at a time to make it easier to pinpoint the cause.
| Symptom | Check first | Next step |
|---|---|---|
| Returns 401 or 403 | Token, permissions, and request requirements | Copy the subscription URL from the provider again, then check its expiration and client requirements |
| HTML tags at the beginning | Login page, error page, or access verification page | Don’t save it as a config; make sure you’re using the subscription endpoint, not a management page |
| YAML syntax error | Indentation, quotes, or a truncated response | Check the surrounding structure at the reported line, and rule out a Base64-encoded response |
| Unknown proxy type | Protocol support in the current core | Check the core version and node parameters; changing the file extension won’t help |
| Config loads, but nodes time out | Address resolution, server port, authentication, and TLS | Check the connection logs, then determine whether the subscription format is relevant |
An HTTP 200 response only means the request received a response; it does not guarantee that the body is a config. Content-Type can offer a clue, but it’s not conclusive. If a URL opens in a browser but the client can’t fetch it, the cause may involve redirects, certificate trust, request headers, or network path differences. Don’t use browser session cookies as a general fix, and don’t disable certificate verification to troubleshoot.
After an update, check where your changes were saved
Updating a remote config usually downloads its content again. If you edit the downloaded file directly, your changes may be overwritten on the next update. To add personal rules, use the client’s supported override, merge, or extension features where available, and check the processing order. These are client-specific features, and their menus and syntax vary.
Also check whether proxy groups reference nodes that were renamed or filtered out, and whether external proxy resources updated successfully. A successful remote config download does not mean every resource it references was fetched successfully.
A checklist for choosing how to import a subscription
- Have a Clash- or mihomo-specific subscription? Import it directly if possible, first confirming it matches your current core to avoid an unnecessary conversion step.
- Have only a generic Base64 subscription? Check whether your client can parse or convert node links. If not, choose a suitable conversion tool.
- Have only a single share link? Find an import option that explicitly supports its protocol. If you need a full config, you’ll also need to set up proxy groups and rules.
- Have a YAML file? First determine whether it’s a full config or a proxy resource, then validate its syntax, references, and core support.
- Replacing a config you’re already using? Keep a working version, switch only after the new config passes validation, and check the node count, proxy groups, and rule behavior.
Format checks answer “Can the data be read?”, core compatibility answers “Can the protocol run?”, and connection logs help determine “Is the service reachable?” Keeping these steps separate can save you from trial and error across subscription conversion, client settings, and network issues. For initial setup, see the Getting Started Guide. For protocols and config fields, consult the Protocol Reference.