Clash Subscription Formats Explained: YAML vs Base64 Node Lists vs Universal Formats, and How to Convert Between Them

Compares the structural differences between common subscription formats — Clash YAML config, Base64-encoded node lists, and various client-specific formats — explains why some links fail to import, and covers what to watch for when converting between formats.

What's actually behind a subscription link

A subscription link is, at its core, just an HTTP/HTTPS address. The client fetches it periodically, receives a block of text, and parses that text into a node list and rule set according to some agreed-upon format. The catch is that "some agreed-upon format" isn't singular. Different proxy ecosystems each developed their own text structure independently, so under the umbrella term "subscription," at least three formats circulate widely today: the YAML config used by the Clash family, the Base64 node list used by v2ray/Shadowsocks-style tooling, and the proprietary JSON formats output by certain panel software. Whether a client can "read" a given link depends entirely on whether it implements a parser for that specific format.

This is exactly why the same subscription link can import cleanly in a Clash client, yet return a format error or an empty list in a client built on a different protocol stack — the link isn't broken; the two sides simply aren't speaking the same "language."

Clash YAML config: structured, readable, and the most capable

The subscription format used by Clash and Clash Meta (mihomo core) is plain YAML text. A complete config typically has several top-level fields:

port: 7890
socks-port: 7891
mode: rule
proxies:
  - name: "HK-01"
    type: ss
    server: example.com
    port: 443
    cipher: aes-256-gcm
    password: "your-password"
proxy-groups:
  - name: "Auto"
    type: url-test
    proxies: [HK-01]
    url: "http://www.gstatic.com/generate_204"
    interval: 300
rules:
  - DOMAIN-SUFFIX,google.com,Auto
  - MATCH,DIRECT

Note that YAML doesn't just describe nodes (proxies) — it also describes how nodes are grouped (proxy-groups) and which rules (rules) route traffic to which group. That's what sets it apart from other formats: a YAML subscription is a complete, runnable policy, not just a list of addresses. But because it carries so much information, YAML is strict about field spelling and indentation depth — a single missing space, or a stray tab mixed into the indentation, can break parsing for the entire config.

Note: YAML is extremely sensitive to indentation — fields at the same level must have exactly the same number of leading spaces, and tabs must never be used for indentation. When editing config files by hand, use an editor with YAML syntax highlighting; a single missing space is very hard to spot with the naked eye.

Base64 node lists: lightweight, but just an "address list"

Another common format comes from the client ecosystems built around Shadowsocks, V2Ray, Trojan, VLESS, and similar protocols. Opening one of these subscriptions usually shows a single unbroken string of seemingly random characters, often starting with something like c3M6Ly8.... What's actually happening is that multiple node links (each in the form ss://…, vmess://…, trojan://…) are joined with line breaks and then Base64-encoded as a whole, so the result is safe to transmit through QR codes and plain-text channels without special characters getting mangled.

After decoding, each line has roughly this structure (using Shadowsocks as an example):

ss://[email protected]:443#HK-01
vmess://eyJ2IjoiMiIsInBzIjoiSEstMDIiLCJhZGQiOiJleGFtcGxlLmNvbSJ9
trojan://[email protected]:443?sni=example.com#HK-03

This format carries far less information than YAML: it only describes which nodes exist, their addresses, and the encryption used — no grouping policy, no routing rules. Once the client has this list, how the rules are defined and how nodes get grouped is entirely up to the client's own built-in defaults. This explains a common source of confusion: the same Base64 subscription, imported into two different clients, ends up with the same number of nodes but completely different group structures and default routing — because grouping logic was never part of the subscription content to begin with; the client fills it in on its own.

Why some links import with no nodes, or fail outright

Given the differences above, import failures generally fall into a handful of categories:

A sensible order of checks: first confirm the subscription link loads and shows content in a browser; then look at what the returned content starts with (YAML typically begins with port: or proxies:, while a Base64 list is one long string with no spaces); finally, check the client's log page — most parse errors report the exact line number.

How to convert between formats

If the subscription format you have doesn't match what your client expects, the usual approach is to run it through a conversion tool rather than editing it by hand. The community widely relies on open-source conversion services such as subconverter: you feed in the original subscription link, and it outputs a new link in the target format (Clash YAML, a generic Base64 list, etc.). The client subscribes to this converted link directly, and future updates flow through automatically.

The two most common conversion directions

  1. Base64 node list → Clash YAML: the conversion service parses the protocol parameters out of each ss:///vmess:///trojan:// link, populates the proxies field, and then fills in a default set of proxy-groups and rules based on the target client type (some services let you pick a specific rule template).
  2. Clash YAML → generic Base64 list: the service keeps only the node information from proxies, re-encodes it as protocol-specific links, and Base64-encodes the result. Grouping and rule information is lost at this step, since the target format has no way to express rules in the first place.

Note: Converting from a structured format down to a plain node list is a one-way loss of information — routing rules and grouping logic don't survive the trip. That's fine for a quick, temporary switch to another client. But if you find yourself relying on the converted link long-term, it's better to ask your subscription provider directly for a link in the native format you need, rather than leaning on repeated re-conversion.

Safety and stability notes for conversion

A conversion service is essentially a middle-man proxy — your original subscription content passes through the conversion server before reaching your client. A few things worth keeping in mind:

Three checks to run before importing

If you're not sure what format a subscription link is in, run through this quick sequence instead of repeatedly guessing and re-importing:

  1. Open the subscription link directly in a browser and look at how the returned content starts — fields like port, proxies, or mixed-port point to Clash YAML; one long string with no line breaks points to a Base64 node list.
  2. Check which core your client is running (Clash Meta / mihomo cores generally have broader compatibility and support more protocol types); if the core is outdated, update the client first before importing.
  3. If the format genuinely doesn't match what your client expects, use a conversion tool, following the safety guidance from the previous section when picking a backend.

Working through these three steps will pinpoint the actual cause behind most "import failed" or "empty node list" problems, without endless trial and error.

Download client