First, distinguish subscription URLs, response formats, and configuration files

A subscription URL is just an entry point for retrieving content. A link that starts with https:// might return a complete Clash config or a list of proxies encoded in Base64. Neither the word “clash” in the URL nor a .yaml file extension tells you what the response contains—check the response body.

Some services return different formats depending on request parameters, the client identifier, or account settings. As a result, the same URL can return different content in a browser and in a client. When troubleshooting, note the import method, the actual response format, and the client’s core. Don’t keep changing the file extension.

FormatHow to identify itWhat it usually containsWhere to import it
Full Clash YAML configFields such as proxies:, proxy-groups:, and rules:Proxies, proxy groups, rules, and other settingsConfiguration file or remote config source
Proxy provider YAMLPrimarily a top-level proxies: listA set of proxies for a main config to referenceResource referenced by proxy-providers
Base64-encoded proxy listOften one URI per line after decodingProxy connection parameters, usually without routing rulesSubscription import or conversion tool that supports this format
Individual proxy URIPrefixes such as ss:// and trojan://One proxy and its protocol parametersProxy import method that supports the protocol

Clash YAML: proxy groups and rules go beyond proxy entries

In a full config, proxies defines connection parameters, proxy-groups defines how proxies are selected, and rules determines where traffic goes. A converter that extracts only proxies will lose the other two. DNS, listening ports, and TUN settings also can’t be fully represented by an individual proxy URI.

Minimal configuration example

Here’s how a typical Trojan proxy fits into a main config. The domain and password are examples only and won’t work for a real connection. 7890 is the local mixed-proxy port; 443 is the remote proxy port. They aren’t interchangeable.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

proxies:
  - name: "demo-trojan"
    type: trojan
    server: edge.example.com
    port: 443
    password: "demo-password"
    sni: edge.example.com
    udp: true

proxy-groups:
  - name: "Manual Selection"
    type: select
    proxies:
      - "demo-trojan"
      - DIRECT

rules:
  - MATCH,Manual Selection

Here, MATCH,Manual Selection is a catch-all rule, not a set of region- or domain-based routing rules. When the proxy group is set to DIRECT, matching connections go directly to their destination. Selecting the example proxy routes them through that proxy instead.

  • name is the identifier used for references. If you rename a proxy, update any entries in proxy groups that still use its old name.
  • server is the connection destination; sni is the server name used in the TLS handshake. They don’t have to be the same in a real deployment.
  • udp: true allows the proxy to handle applicable UDP forwarding, but it doesn’t mean the server or your current connection method supports all UDP traffic.

Base64 decoding restores text; it doesn’t create Clash fields

Base64 is an encoding, not a proxy protocol or encryption. It can wrap a list of proxy links into a block of text, but it won’t add proxy groups, DNS, or rules. If you decode a Base64 string and save it as config.yaml, but it still contains a list of URIs, the Clash config parser still can’t use it as a main YAML config.

Check both layers of content

  1. Start with the outer response body. If it contains structures such as proxies:, inspect it as YAML first—don’t try to decode it.
  2. If the response looks like encoded text, decode it with a local tool and check whether the result is readable.
  3. If each decoded line starts with ss://, trojan://, or a similar prefix, it’s usually a proxy list that still needs protocol parsing and field mapping.
  4. If the result is an HTML error page, login prompt, or JSON error, fix the subscription access issue first. Don’t treat it as proxy data to convert.

For example, aGVsbG8= decodes to hello. That only confirms the text can be decoded; it doesn’t mean the content is a valid subscription. Standard Base64 commonly uses +, /, and trailing = padding. The URL-safe variant uses - and _, and some implementations omit padding. Use a decoder that supports the actual variant; don’t alter the original proxy data arbitrarily.

Also distinguish Base64 used to encode the subscription from Base64 inside a proxy URI. For example, the user info in some Shadowsocks URIs is itself Base64-encoded. After decoding the outer layer to get ss://, parse the URI according to its specification—don’t mechanically decode the entire URI again.

Convert an individual proxy URI to YAML by mapping each connection parameter

The URI below describes the same basic connection details as the earlier Trojan example. It doesn’t include the “Manual Selection” proxy group or the MATCH rule. The fragment at the end provides the proxy name; if the actual name contains spaces, non-ASCII characters, or special symbols, the exporter should encode it according to URI rules.

trojan://[email protected]:443?security=tls&sni=edge.example.com#demo-trojan
URI componentCorresponding YAML fieldWhat to check
trojan://type: trojanThe target core must support the protocol
demo-passwordpasswordHandle percent-encoding according to the specification and preserve the original credentials
edge.example.comserverDon’t use the SNI value to arbitrarily overwrite the connection address
:443port: 443Use an integer from 1 to 65535
sni=edge.example.comsniCheck that it matches the server certificate and deployment requirements
#demo-trojannameDecode the name, then check for duplicates and proxy group references

Each protocol needs its own mapping

Shadowsocks typically requires cipher and password. VMess commonly uses a UUID, transport settings, and TLS parameters. VLESS, Hysteria2, and other protocols also depend on support in the target core. The original Clash and Clash Meta (mihomo) don’t support exactly the same protocols. Specify the target core rather than saying “Clash compatible.”

WebSocket paths and Host headers, as well as gRPC service names, are part of the connection parameters. For WebSocket, a typical mihomo config uses network: ws, ws-opts.path, and ws-opts.headers.Host. If a conversion keeps only the server, port, and password, the proxy may appear in the list but still fail to complete the handshake.

Convert between formats: decide whether you need the proxies or the full config

Convert a Base64-encoded or URI list to Clash YAML

  1. Back up the source. Save the original subscription content and the current working config. Subscription URLs containing tokens are sensitive credentials—keep them out of screenshots, public logs, and issue attachments.
  2. Choose the output target. Select the Clash or mihomo target the tool actually supports, and check that the target supports the proxy protocols you use.
  3. Decode and parse the proxies. Decode only if the outer content is Base64-encoded. Identify the protocol, address, credentials, TLS settings, and transport parameters for each URI.
  4. Choose the output format. To replace proxies in an existing config, generate a proxy list or provider resource. To import a standalone config, generate a main config with proxy groups and rules.
  5. Review template changes. Conversion templates may add DNS, rule providers, or TUN fields. Check each item, and don’t mistake added settings for options from the original subscription.

A client’s “Import from URL” option won’t necessarily support every response format. Some import methods require full YAML, some accept proxy URIs, and others use an additional conversion service. Follow the instructions for the specific client and import method. Renaming a link doesn’t change its response body.

Convert Clash YAML to URIs or Base64

  1. Extract the actual proxies from proxies. If the main config only references proxy-providers, retrieve the corresponding provider resource. The provider URL itself is not a proxy address.
  2. Serialize connection parameters according to each protocol’s URI specification. Clearly record any fields the target client doesn’t support; don’t silently discard them.
  3. Put one URI on each line. Encode the full list only if the recipient requires a Base64 subscription.
  4. Import it into the recipient client, compare the proxy count and key fields, then test the connection.

This reverse conversion is usually lossy. Exporting proxy URIs won’t carry over proxy-groups, rules, dns, tun, or local listening ports. Even if a proxy connects, traffic may behave differently from the original config. Set up routing rules separately on the receiving end.

After conversion: check syntax and actual traffic

“Import successful” only means an import method accepted the file. It doesn’t guarantee that every field was preserved or that every proxy can connect. Validate in this order: rule out structural issues first, then investigate network problems.

Step 1: Validate the config with the target core

If you have the mihomo command-line core installed, run the check below from the directory containing the config. It reads and validates the config; it doesn’t start a persistent proxy service. If the config depends on relative-path resources, have those files ready too, and check the output for resource-loading errors.

mihomo -t -f ./config.yaml

Check YAML indentation, duplicate proxy names, proxy group references, and unsupported protocol fields. Keep quotes around string passwords to avoid interpreting # as a comment or parsing a value as another YAML type. Don’t use tabs instead of spaces for indentation.

Step 2: Compare every field, not just proxy names

  • Count: Compare the number of entries in the original list with the converted list. Any filtered or deduplicated entries should have a clear explanation.
  • Connection: Compare server, port, credentials, encryption method, and TLS parameters.
  • Transport: Check protocol-specific options such as WebSocket paths, Host headers, and gRPC service names.
  • References: Make sure proxy groups point to existing proxies and rules point to existing groups. Group names must match exactly, including spaces and capitalization.
  • Local proxy: The app in this example should connect to 127.0.0.1:7890, not the remote proxy’s 443 port.

Step 3: Test TCP, DNS, and UDP separately

Choose a proxy and use an app explicitly configured to use it to open an HTTPS page. Then check the connection log for the outbound proxy and any errors. A successful latency test only means that test request completed at that moment; it doesn’t prove that video, games, or every website will work. For DNS failures, check the DNS config. For TLS handshake errors, check SNI, the system clock, and the certificate instead of disabling certificate validation.

If HTTP proxy access works but a game still connects directly, the issue may be how traffic is routed into the proxy. Converting proxy formats doesn’t enable TUN or route all app traffic through the proxy automatically. For system-wide routing or UDP forwarding, check TUN, routes, and client permissions separately. These are runtime settings, not Base64 encoding issues.

Common questions and choosing a format

Why does the converter report success when the client says there are no usable proxies?

Check that the output body actually contains a proxies list. Then check whether filters removed all entries, whether the target core supports the protocol, and whether proxy groups still reference old names. A successful HTTP request doesn’t mean the conversion result is valid; the response could simply be an error message from the service.

Will routing rules survive if I convert a config to Base64?

Encoding any text preserves its bytes, but the recipient needs to know what to decode it into. The common “Base64 subscription” format is a list of proxy URIs, not a full YAML config. Encoding an entire YAML file won’t make a client that only recognizes URI lists understand its routing rules.

Will the converted config update automatically?

A file exported locally is a snapshot and won’t sync on its own. Whether a remote conversion URL updates depends on whether it fetches the source each time, how it caches results, and how the client handles updates. When proxies are updated through proxy-providers, the main config still controls its proxy groups and rules.

Should I convert subscriptions locally or use an online service?

Whenever possible, use the target format provided directly by your subscription provider to avoid extra steps. If conversion is necessary, a local tool gives you more control over where credentials go. An online service receives your subscription URL or proxy parameters. Even if the URL is Base64-encoded, the recipient can decode it, so make sure you trust the service first.

There are two main criteria: if you need to move proxies, proxy groups, and routing rules together, use a full YAML config supported by the target core. If you only need to exchange proxies, use URIs or a proxy list supported by the recipient. See the Configuration Reference for field details, or the Client Selection Guide for help choosing a client.