Advanced 9 min read

Clash Config File Structure Explained: What Each YAML Section Does

A section-by-section walkthrough of the config file: ports, DNS, proxies, proxy-groups and rules — field meanings, common values and the indentation mistakes that break configs.

Config File Overview: YAML Basics and Top-Level Structure

Both Clash and Clash Meta (mihomo core) use a plain YAML text file, usually named config.yaml, as their configuration. A subscription link is really just a URL pointing to a file in the same format — the client downloads it, saves it locally, and parses it from there. The whole file is organized around top-level keys, the most common being port, socks-port, mixed-port, allow-lan, mode, log-level, dns, proxies, proxy-groups, rules, and the Meta-core-specific tun. These keys sit at the same indentation level with no nesting between them, and order doesn't strictly affect parsing — but for readability, most configs put runtime settings first and rules last.

YAML expresses hierarchy through indentation. It never recognizes tabs, only spaces, and the indentation width must be exactly consistent within the same level. Strings usually don't need quotes, but if a value contains a colon, a hash sign, or starts with a digit while meant to be treated as a string, wrap it in quotes. List items start with a hyphen and a space; key-value pairs are separated by a colon and a space. These rules sound simple, but they're the root cause of almost every parsing error you'll hit later, so it's worth memorizing them before editing anything.

Runtime Basics: Ports, LAN Access, and Mode

Near the top of the file you'll usually find a set of fields controlling the client's own behavior — which ports it listens on, whether LAN devices can connect, and how traffic is generally handled.

port: 7890
socks-port: 7891
mixed-port: 7893
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
external-controller: 127.0.0.1:9090
  • port: the HTTP proxy listening port — this is the value entered into system proxy settings.
  • socks-port: the SOCKS5 proxy port, needed separately by some CLI tools or game clients.
  • mixed-port: a single port that accepts both HTTP and SOCKS5 requests; most modern GUI clients use only this one, and you can drop port/socks-port if you're using it.
  • allow-lan: whether other devices on the same LAN can use this machine as a proxy. Defaults to false; set it to true when sharing the proxy with a phone or tablet.
  • mode: the core working mode. rule (rule-based routing) is the most common choice; global routes everything through the same node; direct disables proxying entirely and is only useful for temporary debugging.
  • log-level: log verbosity. Switch to debug temporarily when troubleshooting; keep it at info or warning for everyday use so the log panel doesn't get flooded.

Note: if allow-lan is enabled while external-controller is also active without an access secret set, other devices on the LAN can read the control API too. Pair it with the secret field to set an access password.

The DNS Section: Field Meanings and Common Values

The dns section controls how domain resolution works. Configured well, it reduces DNS leaks and resolution latency; configured poorly, it leads to sites failing to load or resolving to the wrong address. A typical block looks like this:

dns:
  enable: true
  ipv6: false
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://doh.example-provider.net/dns-query
    - tls://dot.example-provider.net:853
  fallback:
    - https://fallback-doh.example-provider.net/dns-query
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"
  • enable: whether the built-in DNS server takes over resolution. Disabling it falls back to the system's own DNS settings.
  • default-nameserver: used to resolve the hostnames of the DoH/DoT addresses listed under nameserver. These must be plain IPs, never domain names — otherwise you hit a chicken-and-egg problem of "resolving the resolver's own domain."
  • nameserver: the actual server list used to resolve everyday domains. Supports classic UDP addresses as well as https:// DoH and tls:// DoT, both of which reduce the chance of ISP-level DNS hijacking.
  • fallback: an alternate resolver list used when nameserver suspects a domain's result has been tampered with, typically paired with fallback-filter.
  • enhanced-mode: the enhancement strategy. fake-ip assigns a domain a fictitious internal address and restores the real domain at the exit node — it has the best compatibility and is the default for most clients. redir-host is an older compatibility method and generally not recommended anymore.
  • fake-ip-filter: a list of domains excluded from fake-ip. LAN device names and internal company domains should go here, or you may find internal services become unreachable.

The proxies Section: Filling In Node Fields

proxies is a list where each item describes one usable proxy node. Common protocols include ss (Shadowsocks), vmess, trojan, and hysteria2 (supported by the Meta core). Fields vary slightly by protocol, but every entry always includes a name, server address, and port at minimum.

proxies:
  - name: "Sample-HongKong-01"
    type: ss
    server: node1.example-relay.net
    port: 8388
    cipher: aes-256-gcm
    password: "your-password"
    udp: true

  - name: "Sample-Japan-01"
    type: vmess
    server: node2.example-relay.net
    port: 443
    uuid: 11111111-2222-3333-4444-555555555555
    alterId: 0
    cipher: auto
    tls: true
    network: ws
    ws-opts:
      path: /path
      headers:
        Host: node2.example-relay.net
  • name: the node's display name in the client UI. proxy-groups references nodes by this exact name, so if you rename one, double-check every group that references it still matches.
  • type: the protocol type, which determines which extra fields are needed below.
  • server / port: the node's server address and port, taken directly from your subscription provider.
  • udp: whether UDP forwarding is enabled for this node. Online gaming and some voice calls depend on UDP — keep it on if your client supports it.
  • tls / network / ws-opts: transport-layer and TLS settings covering things like WebSocket paths and disguised hostnames. Usually you can copy these straight from what your provider supplies; back up the original file before hand-editing.

Most users never need to hand-write this entire section — the client regenerates it automatically whenever the subscription updates. Manual editing is mainly for local debugging of a self-hosted node or temporarily fixing a single incorrect value.

The proxy-groups Section: Group Types and Syntax

proxy-groups determines how nodes are categorized and displayed, along with the switching and latency-testing logic. Every group needs at least name, type, and proxies.

proxy-groups:
  - name: "Auto"
    type: url-test
    url: "https://www.gstatic.com/generate_204"
    interval: 300
    tolerance: 50
    proxies:
      - "Sample-HongKong-01"
      - "Sample-Japan-01"

  - name: "Select Node"
    type: select
    proxies:
      - "Auto"
      - "Sample-HongKong-01"
      - "Sample-Japan-01"
      - DIRECT

  - name: "Failover"
    type: fallback
    url: "https://www.gstatic.com/generate_204"
    interval: 300
    proxies:
      - "Sample-HongKong-01"
      - "Sample-Japan-01"
  • select: a manual-selection group shown as a dropdown in the UI — good for the outermost group that users switch by hand.
  • url-test: an auto latency-testing group that pings url at the interval set by interval (in seconds) and automatically selects the node with the lowest latency, within the tolerance margin.
  • fallback: a failover group that tries nodes in list order and automatically switches to the next one when the current node becomes unavailable — good for scenarios where stability matters more than speed.
  • load-balance: a load-balancing group that distributes requests across multiple nodes according to a strategy — useful when you want to combine bandwidth from several nodes.

A group's proxies list can contain individual node names, the name of another group, or the built-in policy names DIRECT and REJECT. This is exactly how a "Select Node" group commonly nests an "Auto" group inside it.

The rules Section: Syntax and Match Order

The rules section is where traffic actually gets routed. Each line follows the fixed format "rule type, match value, target policy," and rules are matched top to bottom — the first match wins and everything below it is ignored, so order matters a great deal.

rules:
  - DOMAIN-SUFFIX,example-streaming.com,Select Node
  - DOMAIN-KEYWORD,example-ads,REJECT
  - DOMAIN,api.example-tool.dev,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,Select Node
  • DOMAIN / DOMAIN-SUFFIX / DOMAIN-KEYWORD: exact match, domain-suffix match, and keyword-in-domain match respectively. Suffix matching is the most common, since one rule covers every subdomain under a domain.
  • IP-CIDR / IP-CIDR6: matches by IP range, commonly used to route LAN or private-network addresses directly. no-resolve skips extra domain resolution and matches on the destination IP directly, cutting unnecessary DNS lookups.
  • GEOIP: matches by the country or region the destination IP belongs to. GEOIP,CN,DIRECT is a line almost every config keeps, so mainland-China-based destinations connect directly without unnecessary detours through the proxy.
  • MATCH: the catch-all rule, placed last, defining how traffic that missed every rule above it should be handled. Omitting this line leaves the fate of unmatched traffic undefined.

Policy names used in rules must exactly match the name values in proxy-groups, including case and character width — one of the details newcomers overlook most often. If a group clearly exists but the client complains the policy doesn't, it's usually a single mistyped character in the name.

Common Indentation and Syntax Errors

When a hand-edited config throws an error, over 90% of the time it's an indentation or punctuation issue. Work through this checklist:

  1. Check whether tabs and spaces got mixed. It's best to replace all tabs with two or four spaces in your text editor and keep it consistent throughout.
  2. Check that list items at the same level are aligned — for example, every - name: under proxies needs the same number of leading spaces.
  3. Check whether a string needs quotes — UUIDs, passwords containing colons, or values starting with a digit should be wrapped in double quotes to avoid YAML parsing them as a different type.
  4. Check whether a rule line accidentally uses a full-width comma. Full-width commas aren't recognized as separators in YAML, and the whole rule will either fail silently or throw an error.
  5. If you can't pinpoint the exact line, comment out sections of the config one at a time and restore them gradually to narrow down the problem quickly.

Verifying Your Changes

After saving, most clients let you "reload config" directly from the UI without restarting the whole program. If loading fails, the client usually reports the exact line number in the log panel or a popup, which you can cross-check against the list above. Once it loads successfully, confirm the change actually took effect by:

  • Checking the proxies page to see whether the node list under the target group matches what you just edited.
  • Switching to the log page, setting the log level to debug, visiting a test domain, and watching whether it hits the expected rule and policy.
  • Using a command-line tool to hit a known IP-check endpoint to confirm the exit node matches what you expect, then switching the log level back to info for everyday use.

Tip: if your config comes from a subscription link, make experimental edits on a separate local copy so the next automatic subscription update doesn't overwrite your manual changes.

Get Clash

Download Clash

Get a client with full YAML config parsing and hot reload support, so you can follow along and edit as you read.

Download Clash