Formats & Options Reading time: 12 minutes

Clash Subscription Formats: Converting YAML, Base64 Links, and sing-box JSON

Compare common subscription formats, learn how clients identify them, and follow practical steps for conversion with open-source tools or a self-hosted service.

Identify the subscription format first

Here is the key point: Clash and Mihomo usually use YAML configuration, sing-box uses JSON, and a seemingly garbled subscription is often just a collection of share links encoded with Base64. These formats overlap in the information they carry, but changing a file extension does not convert one into another.

A subscription link is only an address used to retrieve content; it is not the content format itself. A server can return Clash YAML, generic share links, or sing-box JSON from the same https:// address, depending on the client parameters. Inspect the response body instead of relying on the URL extension.

Identify the format from the opening characters

Content you see Likely format Next step
proxies:, proxy-groups: Clash or Mihomo YAML Import it into a compatible client and check the configuration fields
dm1lc3M6Ly8, continuous letters, numbers, and equals signs Base64-encoded text Decode it first, then check for multi-line share links
ss://, trojan://, vless:// One or more URI share links Use a converter to generate the target configuration
{"log":, "outbounds" sing-box JSON Validate it with sing-box; do not import it directly into Clash
HTML, a login prompt, or an error message Subscription request failed Check the URL, expiration date, and request parameters

Read the response as text instead of opening it directly

Use the browser developer tools' Network panel to inspect the response, or save it as plain text. Command-line users can use curl and specify an output filename to keep long content from flooding the terminal.

curl -L --max-time 20 "https://sub.example.net/api/demo-token" -o subscription.txt
head -n 8 subscription.txt

-L follows redirects, while --max-time 20 limits the entire request to 20 seconds. If the first line is <!doctype html>, you received a web page rather than a subscription configuration. Resolve any login, expired URL, or gateway interception issue first.

Structural differences between YAML, Base64, and sing-box JSON

The difficult part of conversion is not syntax but the underlying model. Node addresses, ports, and credentials are relatively easy to map. Policy groups, rule sets, DNS behavior, TUN routing, and script extensions may exist only in one core. A converter can rewrite structure, but it cannot automatically understand the intent of every rule.

Clash and Mihomo YAML

YAML configurations commonly contain nodes, policy groups, and routing rules together. Mihomo is an open-source proxy core that continues the Clash configuration ecosystem and supports many protocols and extension fields. Here is a minimal example:

mixed-port: 7890
mode: rule
allow-lan: false

proxies:
  - name: HK-01
    type: ss
    server: edge.example.net
    port: 8388
    cipher: aes-128-gcm
    password: demo-pass

proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - HK-01
      - DIRECT

rules:
  - DOMAIN-SUFFIX,example.org,PROXY
  - MATCH,PROXY

mixed-port: 7890 means that HTTP and SOCKS requests share port 7890. proxy-groups defines policies selectable in the client, and rules matches traffic from top to bottom. Some clients can fill in missing groups and rules automatically when only a node list is provided; others report that the configuration is unavailable.

Base64 collections of share links

Base64 is neither a proxy protocol nor a complete configuration format. It encodes bytes as text for easier transport. A common subscription joins multiple ss://, trojan://, vmess://, or vless:// links and then encodes the result with Base64.

ss://[email protected]:8388#HK-01
trojan://[email protected]:443?security=tls#SG-01

This type of content usually carries only node parameters and display names, not complete Clash rules. When converting it to YAML, a tool often adds proxy-groups, rules, and DNS settings from a template. As a result, the same nodes can behave very differently with different templates.

sing-box JSON

sing-box uses JSON to describe inbounds, outbounds, routing, and DNS. In a sing-box 1.12 configuration, nodes are usually placed in the outbounds array, and a selector is also an outbound object:

{
  "log": {
    "level": "info"
  },
  "outbounds": [
    {
      "type": "shadowsocks",
      "tag": "hk-01",
      "server": "edge.example.net",
      "server_port": 8388,
      "method": "aes-128-gcm",
      "password": "demo-pass"
    },
    {
      "type": "selector",
      "tag": "proxy",
      "outbounds": [
        "hk-01"
      ]
    }
  ],
  "route": {
    "rules": [
      {
        "action": "route",
        "domain_suffix": [
          "example.org"
        ],
        "outbound": "proxy"
      }
    ],
    "final": "proxy"
  }
}

Clash proxy-groups can be mapped approximately to sing-box selector and urltest, but their field names and execution models differ. Clash MATCH usually corresponds to the final outbound in sing-box routing, rather than being copied as a rule with the same name.

Decode Base64 before choosing a conversion target

Do not send every long string straight to a converter. Decode it locally and inspect the first few lines to confirm that the content is complete and avoid mistaking an error page, compressed data, or a second encoding layer for a node subscription.

Decode with Windows PowerShell

$raw = (Get-Content .\subscription.txt -Raw).Trim()
$bytes = [Convert]::FromBase64String($raw)
[Text.Encoding]::UTF8.GetString($bytes) |
  Set-Content .\decoded.txt -Encoding utf8
Get-Content .\decoded.txt -TotalCount 8

If FromBase64String reports a format error, check whether the text contains spaces, HTML tags, or URL-safe characters. URL-safe Base64 may use hyphens and underscores instead of plus signs and slashes, and may omit trailing equals signs. Use a tool that supports this variant.

Decode on Linux and macOS

# GNU/Linux
base64 -d subscription.txt > decoded.txt

# macOS
base64 -D subscription.txt > decoded.txt

sed -n '1,8p' decoded.txt

If the decoded result is still one long Base64 string, it may be double-encoded, or it may be JSON encoded inside a VMess link. Check the prefix first: a subscription encoded twice can be decoded again, but the content after vmess:// belongs to a single node and should not be sent to a standard Base64 command together with the line prefix.

Generate Clash YAML with an open-source converter

When the source is a URI list or Base64 subscription and the target client runs Mihomo, use an open-source subscription converter that supports Clash output. A common implementation provides a /sub endpoint that accepts a source URL, target type, and rule template, then returns YAML.

Confirm three parameters before converting

  1. Target type: Choose Clash or an output explicitly marked for Mihomo or Clash Meta. An older Clash target may remove newer protocol fields.
  2. Source URL: URL-encode it, especially when the address itself contains ?, &, or equals signs.
  3. Rule template: Node conversion and rule generation are separate tasks. Start with a simple template, verify connectivity, and only then add remote rule sets.

Assuming a local conversion service listens on 127.0.0.1:25500, request Clash output using an encoded source URL as follows:

curl "http://127.0.0.1:25500/sub?target=clash&url=https%3A%2F%2Fsub.example.net%2Fapi%2Fdemo-token" \
  -o converted.yaml

Supported target names vary between projects and branches. Some versions support clash, while certain extensions also provide Mihomo or sing-box targets. Check the target list for the current build instead of guessing from the endpoint name. If the tool cannot output sing-box, use an implementation with the appropriate adapter rather than simply renaming YAML to .json.

Check syntax before importing

Mihomo can check a configuration from the command line. Assuming the executable is named mihomo and the configuration file is converted.yaml in the current directory:

mihomo -t -f ./converted.yaml

A successful test only means that the configuration can be parsed; it does not mean every node can connect. Start the client, load the file from the Subscription or Configuration page, and check the Proxy page for nodes in the policy groups. Finally, open Settings → System Proxy and confirm that the HTTP and SOCKS ports match the configuration, such as both pointing to mixed port 7890.

A reliable workflow for self-hosting a conversion service

Subscription URLs often contain access credentials. If conversions are frequent, run the open-source converter locally or on a controlled server so the source URL travels only between your device and the subscription server. Self-hosting also makes it easier to pin versions and rule templates, reducing differences between conversions on different dates.

Basic local setup

  1. Obtain a build matching your operating system and CPU architecture from the project's release records, such as Windows x64, Linux amd64, or macOS arm64.
  2. Place the program and configuration files in a dedicated directory. On first launch, listen only on 127.0.0.1; do not bind directly to a public network interface.
  3. Confirm the listening port, such as 25500, then access the local endpoint with a browser or curl.
  4. Store rule templates locally and record the converter version, template version, and output time.
  5. Test one node first, then process the full subscription after confirming that field mapping is correct.

If the conversion service must run on a local network server, restrict its source URLs and add access control at the reverse proxy layer. Conversion endpoints often allow callers to submit arbitrary subscription URLs. Without restrictions, they may expose subscription content or let others use the server to request internal network addresses.

Keep inputs and outputs fixed for easy rollback

Keep three files: the original response source.txt, the converted output converted.yaml or config.json, and conversion-notes.txt containing the version and parameters. For example, record port 25500, target clash, the template filename, and the conversion date. If the node count changes unexpectedly, you can quickly determine whether the source, template, or tool upgrade caused it.

Mapping Clash YAML to sing-box JSON

YAML-to-JSON conversion is not merely a syntax change. A general YAML-to-JSON tool can change indentation-based structures into braces, but it cannot turn Clash proxies into sing-box outbounds or understand policy groups and routing rules. Use a converter that understands both proxy configuration models.

Key field mappings

Clash / Mihomo sing-box Conversion note
proxies[].name outbounds[].tag Tags must be unique; rename duplicate names
server, port server, server_port The port field has a different name
select in proxy-groups selector outbound Member names must become the corresponding tags
url-test urltest outbound Recheck the test URL, interval, and tolerance
rules route.rules Rule types and the final outbound cannot be copied mechanically
dns dns with routing Resolver tags, routing conditions, and caching behavior differ
tun tun in inbounds Reset interface addresses, auto-route, and strict-route settings

Protocol fields may also differ. TLS server names, ALPN, Reality parameters, WebSocket paths, and request headers are nested differently in the two configurations. If a node appears but its handshake fails, compare these fields first instead of repeatedly changing the local port.

What to do when rules cannot be fully mapped

  1. Convert one node first, set it as the final route, and verify the protocol parameters.
  2. Add one manual selector and confirm that node tags match its members.
  3. Add LAN and common direct-connection rules, then verify that local devices still work.
  4. Import domain, IP, and rule sets next, and observe which rules are actually matched in the logs.
  5. Enable TUN and complex DNS routing last, avoiding several variables at once.

Ten fields to review after conversion

Do not immediately overwrite the configuration in use. Save the converted file separately and check each item below. These checks matter more than whether the file imports successfully.

  1. Node count: If the source has 36 nodes, the output should not contain only 3. When nodes disappear, check whether the target format or converter filtered their protocols.
  2. Node names: Names must be unique. Duplicate names may cause a policy group to reference only one node.
  3. Server and port: Confirm that server was not replaced with the subscription server address, and verify actual ports such as 443, 8443, and 8388.
  4. Credentials: Check passwords, UUIDs, keys, and letter case. Make sure URL decoding did not turn plus signs into spaces.
  5. TLS parameters: Verify the server name, certificate verification setting, ALPN, and Reality public key fields.
  6. Transport parameters: Preserve the leading slash in WebSocket paths. Do not interchange the gRPC service name and HTTP Host.
  7. Policy group members: Manual selection, latency testing, and failover groups must contain valid nodes, not just a group name.
  8. Rule order: Rules are matched in order. LAN direct-connection rules generally belong before the final fallback rule.
  9. DNS behavior: Check the listening address, upstream servers, and the split between proxied and direct DNS resolution to avoid loops.
  10. Local port: If the configuration changes to 7891, also update Windows 11 Settings → Network & Internet → Proxy. The old 7890 setting will not follow automatically.

Verify the result with the shortest path

Disable TUN first and enable only the system proxy and one manual node. Visit an exit-IP lookup page, then use the command line to request an HTTPS address through the mixed port:

curl -x http://127.0.0.1:7890 --connect-timeout 8 https://example.com/

If it works, test rule mode, automatic latency testing, and TUN in sequence. An 80 ms latency result only means that the probe address responded quickly; it does not guarantee stable access to every website. Proper verification also requires checking DNS, the TLS handshake, and the download process.

Frequently asked questions

Can sing-box read YAML after changing its extension to JSON?

No. Changing the extension does not change the internal data model. Even if a general-purpose tool first converts YAML syntax to JSON, the result still contains Clash proxies, proxy-groups, and rules. sing-box will not automatically interpret them as outbounds and routes.

Why does Base64 decoding produce nodes but no rules?

Generic URI subscriptions mainly carry node parameters and usually do not include Clash policy groups or routing rules. Choose a rule template when generating YAML, or maintain the policy groups and rules yourself in the converted result.

Can a converted subscription still update automatically?

It depends on how it is imported. A locally exported static file does not update automatically. If the client stores the conversion endpoint URL, it can request a new result at the configured interval. Keep the original URL and confirm that the conversion service remains available.

Can a Mihomo configuration be used directly with an older Clash version?

Basic fields may be compatible, but Mihomo extension protocols, rule sets, DNS, and TUN fields may not be recognized by an older core. When using an older target client, choose its corresponding output type and validate the file with that core's own configuration check command.

All converted nodes time out. What should I check first?

First check whether the latency-test URL is reachable, then confirm that the policy group actually contains nodes. If manual connections also fail, compare the server, port, TLS server name, and transport path. If manual connections work, the issue is usually the test URL, interval, or concurrency setting.

Choosing the right format

For a Mihomo client, prefer Clash or Mihomo YAML supplied directly by the server. For sing-box, prefer JSON generated for the current sing-box configuration structure. Add a conversion layer only when the source does not provide the target format.

Base64 URI subscriptions work well as a general node source, but they do not provide complete traffic routing. For long-term use, manage node conversion and rule templates separately: update nodes from the subscription and maintain routing rules in a configuration you control. This makes it easier to tell whether a problem comes from changed node parameters or from routing and DNS settings.

Keep one simple principle in mind: validate one node before adding policy groups; verify the system proxy before enabling TUN; check syntax before troubleshooting the network. Fewer variables mean faster diagnosis.

Get the Client View all platform options