Clash Meta Download Guidemihomo client downloads

mihomo Config File Basics: Understanding the YAML Structure

Config & subscriptions Jul 2, 2026 3 min read
On this page

Everything mihomo does is driven by a single file: config.yaml. Ports, routing rules, DNS behavior, the list of servers — it is all declared there in YAML, a human-readable format that mihomo inherited from Clash and extended. Most people never write this file from scratch, because a subscription generates it for them. But sooner or later you will want to read one: to fix a startup error, tweak a rule, or understand why traffic goes where it goes.

This guide covers the mihomo config file from the ground up: the YAML syntax rules that cause 90% of errors, what each top-level field does, a minimal configuration you can actually run, and how to validate a file before starting the core.

YAML syntax rules that actually matter

  • Indent with spaces, never tabs. Two spaces per level is the convention. A single tab character anywhere will stop the file from parsing.
  • Put a space after every colon. mode: rule is valid; mode:rule is not.
  • Keep nesting consistent. Items in the same list or map must start at the same column.
  • Quote values with special characters. Names containing :, # or emoji are safest inside double quotes.
  • Beware invisible characters. Text copied from chat apps or web pages can carry full-width colons, smart quotes or non-breaking spaces that look identical but break parsing. Retype the character if a line refuses to work.

Top-level fields at a glance

FieldWhat it does
mixed-portOne local port that accepts both HTTP and SOCKS proxy connections
modeOutbound mode: rule, global or direct
log-levelVerbosity of core logs: silent, error, warning, info, debug
external-controllerAddress of the control API used by dashboards and GUI clients
dnsBuilt-in DNS resolver settings, including enhanced-mode
proxiesThe list of individual servers (nodes)
proxy-groupsGroups that organize nodes for selection and automation
rulesRouting rules that map traffic to groups or policies

A minimal config you can run

The file below starts a local HTTP/SOCKS listener and sends all traffic out directly — no servers yet, but it parses, runs, and gives you a skeleton to extend:

mixed-port: 7890
mode: rule
log-level: info
external-controller: 127.0.0.1:9090

proxies: []

proxy-groups: []

rules:
  - MATCH,DIRECT

Save it as config.yaml, run mihomo -d . in the same directory, and point a browser at 127.0.0.1:7890 to confirm the listener works. The port here is just an example value — in GUI clients, check the settings page for the actual mixed port (commonly 7890 or 7897).

How proxies, groups and rules fit together

The three big sections form a chain. proxies defines the raw endpoints. proxy-groups organizes them into named units — a manual selector, an auto-test group, a fallback chain — and each group type behaves differently. Finally, rules decides which traffic goes to which group, evaluated top to bottom; the rule types and matching order deserve their own article. A rule never points at a bare server directly in well-structured configs — it points at a group, which keeps everything switchable.

Validate before you run

mihomo has a built-in test mode that parses a config without starting anything:

mihomo -t -f config.yaml

On success it prints a test-passed message; on failure it names the problem and usually the line number. Run this after every manual edit — it takes a second and catches mistakes before they take your connection down.

Reading common error messages

  • "found a tab character" or "mapping values are not allowed" — indentation problem. Go to the reported line and rebuild the whitespace with plain spaces.
  • "already defined" / duplicate key — the same field appears twice at the same level, often after pasting a snippet. Delete one.
  • "unmarshal errors" naming a field — the value has the wrong type, such as text where a number belongs (mixed-port: "abc").
  • A proxy or group "not found" — a rule or group references a name that does not exist; names must match exactly, including case and emoji.

Tip: when an error makes no sense, check the line above the reported one — YAML parsers often notice a mistake only on the following line.

Once the structure feels familiar, the next layer worth understanding is the resolver: the DNS section and its fake-ip mode explain much of mihomo's behavior that otherwise looks like magic.