Import
Chute can import proxy configuration written for other clients. Two kinds of input are accepted: single-node share links (ss://, vmess://, …), and whole profiles in Clash/mihomo YAML or sing-box JSON. Both are converted into native Chute configuration — what you get afterwards is an ordinary Chute profile with [Proxy], [Proxy Group] and [Rule] sections, not a foreign file that Chute keeps interpreting.
http:// and https:// addresses are never treated as share links. They are subscription addresses: the content is downloaded first, then imported according to what the body turns out to be.
Share Links
Share links — a single link, or a subscription whose body is a list of them — are imported by Chute Mac only. Chute iOS has no share-link import: its first-run guide can set up one server from a scanned QR code carrying an ss://, vmess://, vless://, trojan://, hysteria2://, socks5:// or ssh:// link, and takes little more than the server address, port and credentials from it — a link without a port gets the default from the table below. Chute tvOS and Chute Android do not read share links.
| Scheme | Resulting policy type | Default port |
|---|---|---|
ss:// |
ss |
8388 |
vmess:// |
vmess |
443 |
vless:// |
vless |
443 |
trojan:// |
trojan |
443 |
hysteria2://, hy2:// |
hysteria2 |
443 |
tuic:// |
tuic |
443 |
anytls:// |
anytls |
443 |
socks5://, socks:// |
socks5 |
1080 |
ssh:// |
ssh |
22 |
Most links use the userinfo@host:port?query#name shape. Two are different: vmess:// carries a base64-encoded JSON object (the v2rayN format, with the add / ps / scy / net / aid field names), and ss:// accepts both SIP002 (base64(method:password)@host:port) and the older whole-body base64(method:password@host:port) form. Base64 payloads may be unpadded and may use the URL-safe alphabet.
trojan://password@example.com:443?sni=example.com&alpn=h2,http/1.1#Tokyo%20Node
converts to:
[Proxy]
Tokyo Node = trojan, example.com, 443, password=password, tls=true, sni=example.com, alpn=h2|http/1.1
The text after # is percent-decoded and becomes the policy name; vmess:// takes it from the ps field instead. A link with no name is named host:port. Characters the configuration format reserves — =, ,, [, ], ", tab and newline — are replaced with spaces in the name.
Trojan, Hysteria2, TUIC and AnyTLS are TLS-only protocols, so tls=true is added even when the link does not spell it out.
Multiple links. A payload can be many share links separated by newlines, optionally wrapped in one outer layer of base64. Every line that parses becomes a policy, and repeated names get a 2, 3 … suffix so that rules and groups can still address each node individually. Lines that cannot be parsed are reported as warnings while the rest of the payload is still imported; the import only fails when nothing at all could be converted.
A link whose scheme is not in the table above is not recognized as a share link. A link with a known scheme but missing required fields is rejected with a message naming that scheme.
Supported Parameters
Only the query parameters below are read; anything else in a link is ignored.
"Query links" below means every scheme that carries its settings in a query string: vless://, trojan://, hysteria2://, tuic://, anytls://, socks5:// and ssh://. ss:// and vmess:// are read by their own parsers and are covered after the table.
| Parameter | Applies to | Converted to | |
|---|---|---|---|
sni, peer, servername |
Query links | sni |
|
alpn (comma-separated) |
Query links | alpn (values joined with `\ |
`) — read by TUIC, Hysteria2 and MASQUE policies only, see Common Parameters |
fp |
Query links | fingerprint (the uTLS ClientHello profile) |
|
allowInsecure, insecure, skip-cert-verify |
Query links | skip-cert-verify=true |
|
security=tls, xtls, reality |
Query links | tls=true; on socks5:// this selects the socks5-tls policy type |
|
pbk, sid |
REALITY | reality=true, public-key, short-id, and server-name= from sni / servername |
|
flow |
VLESS | xtls=true, flow |
|
type/network=ws + path, host |
Query links | ws=true, ws-path, ws-headers=Host:… |
|
type/network=grpc + serviceName, servicename (or path) |
Query links | grpc=true, grpc-service-name |
|
type/network=xhttp or splithttp + path, host, mode |
Query links | xhttp=true, xhttp-path, xhttp-host, xhttp-mode |
|
obfs, obfs-password (also obfs_password), up, down |
Hysteria2 | Same option names | |
plugin=… |
Shadowsocks | See below |
ss:// reads plugin and nothing else from the query, so sni, alpn, fp, allowInsecure, security and type= written into a Shadowsocks link are ignored. vmess:// has no query at all: it takes the same settings from the sni, host, alpn, fp, net, path and tls fields of its JSON body. And the three transport rows — ws, grpc, xhttp — never reach a hysteria2://, tuic:// or anytls:// link: those policies are written with their own options and the TLS ones only, since each protocol carries its own transport.
A Shadowsocks plugin value is read as name;key=value;…. obfs-local / simple-obfs / obfs become obfs and obfs_param. v2ray-plugin becomes Shadowsocks over WebSocket: ws=true, path as ws-path, host as the Host in ws-headers, and tls as tls=true with sni set to that host; a mux of 0, false, no or off becomes ws-mux=false, and any other value keeps the default. Its quic mode has no equivalent: the plugin is dropped with the warning <path>.plugin: Shadowsocks plugin 'v2ray-plugin' in quic mode has no KLNEKit equivalent; the proxy will not connect without it. Any other option of it is dropped with <path>.plugin-opts.<key>: option has no KLNEKit equivalent and was dropped. Any other plugin produces a warning and is dropped: the policy is still written, but it will not connect to a server that requires the plugin.
Notice: A non-zero VMess
aid(alterId) is reported as a warning. Chute speaks VMess AEAD only, and a server still requiring the legacy MD5 handshake will not authenticate.
Profile Import
Three formats are recognized:
| Format | Handling |
|---|---|
| Native Chute, Surge or Shadowrocket profile | Used as-is, no conversion step — see Surge and Shadowrocket Profiles |
| Clash / mihomo YAML | Converted to native configuration |
| sing-box JSON | Converted to native configuration |
The format is detected from the content, with the filename used only as a hint. Content starting with { is treated as sing-box JSON whatever the file is called (a sing-box profile saved as .yaml still parses as YAML, so the name alone cannot be trusted). Otherwise a .conf extension means native, .json means sing-box, and .yaml / .yml means Clash. When there is no usable filename — a subscription body, for instance — the first meaningful line decides: #!MANAGED-CONFIG or a [Section] header means native, and proxies:, proxy-groups:, rules:, proxy-providers: or rule-providers: means Clash. Anything else is treated as native. What an address serves — a download or a subscription — is judged by its body: the name taken from the address counts only when the body shows none of these markers, so an address ending in .conf that serves Clash is still converted.
A document that parses but contains none of the sections that define its dialect is rejected rather than reported as a successful import of nothing: Clash YAML needs at least one of proxies, proxy-groups, rules, proxy-providers or rule-providers, and sing-box JSON needs outbounds, endpoints or route.
A single unconvertible entry never fails the import. Each proxy, group and rule is converted on its own; the ones with no Chute equivalent are skipped and reported. The result carries the converted configuration, a list of warnings, and a list of the source fields that were skipped. The same warnings are also written into the converted text as comments, next to the section they came from:
[Proxy]
HK 01 = ss, example.com, 8388, aes-128-gcm, password
# KL-CONVERT-WARNING [proxies[3]]: proxy type 'snell' was skipped — Snell is a Surge-proprietary protocol KLNEKit does not implement
Finally, the converted text is re-parsed with Chute's own parser. Any line the parser rejects is commented out as # KL-CONVERT-DROPPED: … and reported, so a profile that is 95% convertible still imports and runs.
Node names are rewritten where they would break the configuration format: , becomes a space and = becomes -, and a name that then collides with another one gets a numeric suffix. Group members and rule destinations are rewritten to match, so every reference keeps pointing at the same node. direct proxies/outbounds are mapped onto the built-in DIRECT, and reject / block / dns onto REJECT.
Notice: A converted profile is a static snapshot. Chute re-downloads a subscription and parses it as a native profile, so a profile that had to be converted is saved without an auto-update URL and will not refresh itself.
Clash / mihomo Conversion Notes
Notice:
dialer-proxyis converted tounderlying-proxy. The imported reference is active: the policy's connections — TCP, and UDP where the protocols allow it — are opened through the named upstream, and nested references create multiple hops. Missing or cyclic references fail closed and are reported in the log. Adialer-proxynaming atype: directalias is a direct dial. A proxy provider'soverride: dialer-proxybecomes the provider'sunderlying-proxy; the otheroverridekeys are still dropped with a warning. A rule or proxy provider'sproxy:becomes itspolicy=, so the provider is downloaded through that policy, as in mihomo.
- Proxy types converted:
ss,ssr,vmess,vless,trojan,http,socks5,hysteria2,tuic,anytls,wireguard,ssh. Types Chute has no implementation for —snell,hysteria(v1),mieru,juicity,shadowquic,trusttunnel,openvpn,sudoku,vmess-http— are skipped with a warning naming the protocol. Two more are skipped although Chute supports the protocol: amasqueproxy, because the mihomo field layout differs, and atailscaleproxy, which is configured once in the[Tailscale]section and used through the built-inTAILSCALEpolicy. There is notype: https: an HTTPS proxy istype: httpwithtls: true, as mihomo writes it, andtype: httpsis reported as an unsupported proxy type. - mihomo's two fingerprint keys mean different things and are kept apart:
client-fingerprintbecomesfingerprint(the uTLS ClientHello profile) andfingerprintbecomescert-fingerprint-sha256(a certificate pin). udp: falsebecomesudp-relay=falseandtfobecomestfo=true. An enabledsmuxblock is not carried over — Chute'smuxuses a framing of its own, which a mihomo or sing-box server cannot read — and the import says so:<path>.smux: multiplexing (smux) has no KLNEKit equivalent; mux is left off.- An
ssproxy'spluginis converted from itsplugin-opts:obfs(alsosimple-obfs,obfs-local) intoobfsandobfs_param, andv2ray-pluginas for a share link —mode,tls,host,pathandmuxas described there,headersintows-headers, where aHosttakes the place ofhost, andskip-cert-verifyintoskip-cert-verify=true. mihomo's default Host,bing.com, is not copied: without ahost, the policy's own default applies. Any other plugin is reported and dropped. - An
ssproxy'sudp-over-tcp: truebecomesudp-over-tcp=true, always with a version:udp-over-tcp-versionas given, or1when it is left out, because mihomo's default is the legacy framing while Chute's is 2. Withudp: falsethe proxy still relays no UDP, as in mihomo. - A
trojanproxy always getstls=true: mihomo's Trojan is always TLS, so atls: falsein the profile is ignored. Awireguardproxy keeps itsallowed-ips, which Chute enforces — see WireGuard Configuration. - An
sshproxy'shost-keybecomes a quotedserver-fingerprint. A list becomes oneserver-fingerprint="…"holding every key; an entry containing a quote or a comma cannot be written into the policy line and is reported and dropped. - A field that takes one value but is written as a list or a mapping is treated as absent; when the field is required, the entry is reported and skipped.
- Group types
select,url-test,fallbackandload-balanceare converted with their health-check options. Arelaygroup stays arelaygroup with its members in the same order: the first is dialled directly and the last connects to the destination.use:members becomepolicy-provider:<name>references, andinclude-all/include-all-proxies/include-all-providersare expanded into an explicit member list. filterandexclude-filterare carried over quoted, but a pattern containing a comma or a quote cannot survive the configuration line format and is dropped with a warning.- A group's
exclude-typeis carried over asexclude-type=: the named proxy types are kept out of the members a provider contributes.tcp-concurrenthas no switch of its own — Chute races up to five resolved addresses of a destination where the platform allows it, and connects to the first elsewhere — and the import says so rather than reporting it as a plain loss. - Rule types are renamed where the names differ:
MATCH→FINAL,DST-PORT→DEST-PORT,SRC-IP-CIDR→SRC-IP.REJECT-DROPandREJECT-TINYGIFare kept, since both are Chute built-ins with their own behavior; a rule targetingPASSorCOMPATIBLEis skipped. - An inline
rule-provider(type: inlinewith apayloadlist) is expanded into the equivalent concrete rules, since a Chute[Rule Provider]line cannot embed a payload. - A
SUB-RULE,(condition),namerule and thesub-rules:mapping it names are expanded into ordinary rules: each rule of the branchnamebecomesAND,((condition),(rule)),POLICY, and the branch'sMATCH,Xbecomescondition,X. ASUB-RULEinside a branch stacks its condition on the ones around it, up to 8 levels deep. A branch that is missing, or that leads back to one being expanded, is skipped with a conversion warning. - General keys are mapped where an equivalent exists:
mixed-portbecomes the HTTPport(SOCKS5 needs its ownsocks-port),allow-lanbecomesallow-wifi-access,log-levelis mapped ontologlevel,external-controller/secretbecome the external HTTP controller options, and an enabledsnifferbecomessniffing-enabled. bind-addressbecomesinterfaceandsocks-interface— the address the two listeners bind to.*means every address. Ifallow-lanis also on, Chute'sallow-wifi-accesswidens the bind to every address anyway, and the import says so: dropallow-wifi-accessto keep the narrower one.authenticationbecomes onehttp-authline per credential, guarding the same two listeners. An entry with no:between user and password is reported and dropped.external-controller-corsbecomesexternal-http-corsonly when the allowed origins are already "any" (*, or no list at all). Chute's switch is all-or-nothing, so a profile naming specific origins keeps it off and is told why — turning it on would hand every origin the access the profile granted one.allow-private-networkhas no equivalent and the header is not sent.- mihomo splits exact and glob process matching into two rule types; Chute has one, and it is the glob one.
PROCESS-NAME-WILDCARDandPROCESS-PATH-WILDCARDtherefore becomePROCESS-NAMEandPROCESS-PATH, which read*and?the same way. A literal with neither in it still matches exactly. tunmaps where Chute has the same key:dns-hijackbecomeshijack-dns(mihomo'sany:53is rewritten to*:53),route-addressbecomestun-included-routesandroute-exclude-addressbecomestun-excluded-routes.stack,auto-route,auto-detect-interface,auto-redirect,mtu,strict-route,endpoint-independent-nat,device,inet4-address,inet6-address,udp-timeoutandgsoare reported instead — Chute decides those itself.- The DNS block maps as follows.
hostsbecomes[Host]entries, keeping every address of a list.nameserverandfallbackare merged into one set and written asdns-server,doh,dot,doqordoh3according to each entry's spelling — Chute queries every configured resolver at once, so a separate fallback pool has nothing to fall back from, and the import says so.direct-nameserverandproxy-server-nameserverbecomedirect-dns-serverandproxy-dns-server.fake-ip-filterbecomesalways-real-ip.nameserver-policybecomes one[Host]entry per key; arule-set:key becomes the set-keyed formRULE-SET:<provider> = server:…when the provider is anhttporfileone, and ageosite:key is dropped with a warning. - Also in the DNS block:
use-system-hosts: falsebecomesread-etc-hosts = false.use-hosts: falsehas no equivalent — the[Host]table is always consulted — and is reported.fake-ip-filter-mode: whitelistinverts the filter, whichalways-real-ipcannot express, so the list is kept as a blacklist and the import says so.default-nameserverbootstraps the resolvers' own hostnames; Chute resolves those through the system resolver, and the import points at the[Host]line that pins them instead.
sing-box Conversion Notes
- Outbound types converted:
shadowsocks,vmess,vless,trojan,hysteria2,tuic,anytls,shadowtls,wireguard,http,socks,ssh.selectorandurltestbecomeselectandurl-testpolicy groups. Ashadowsockspluginis converted forobfs-local(also spelledsimple-obfsorobfs), intoobfsandobfs_param, and forv2ray-plugin, whoseplugin_optsstring (tls;host=…;path=…) converts as a share link's does, its warnings namingplugin_optsrather thanplugin-opts; any other plugin is reported and dropped, and the outbound is still written but will not connect to a server that requires the plugin. Atrojanoutbound getstls=trueonly when itstls.enabledis set, as in sing-box; without it the outbound is imported as plaintext Trojan — addtls=trueunless the server really speaks plaintext. - Inside an outbound: a
transportof typexhttporsplithttpbecomesxhttp=truewithxhttp-path,xhttp-host,xhttp-modeandxhttp-headers. An enabledtls.echbecomesech=true, and itsconfigbecomesech-config=. REALITY'spublic_keybecomespublic-key; an outbound without one is converted with a warning, since its REALITY handshake cannot succeed. An SSHhost_keylist becomes one quotedserver-fingerprint="…"holding every key; an entry containing a quote or a comma is reported and dropped. A legacywireguardoutbound keeps itslocal_addresslist asself-ipandself-ip-v6(the first address of each family), itspre_shared_keyaspreshared-keyand itsreservedas a quotedreserved="a,b,c"; apeerslist is reported and dropped, since Chute configures a single peer. endpoints(sing-box 1.11 and later) are converted too: awireguardendpoint becomes awireguardpolicy with its own[WireGuard <tag>]section, its peer'sallowed_ipsbecoming the section'sallowed-ips, and the firsttailscaleendpoint becomes the[Tailscale]section, used through the built-inTAILSCALEpolicy. Other endpoint types are skipped with a warning. The section name is the policy name with whitespace and square brackets stripped out, because the configuration line format drops spaces when it matchessection-name=; two policies that would collide after stripping get a-2,-3… suffix.- Dial fields map as on the mihomo path:
tcp_fast_openbecomestfo=trueandnetwork: tcpbecomesudp-relay=false. Ashadowsocksoutbound'sudp_over_tcp—true, or{"enabled": true, "version": 1}— becomesudp-over-tcp=true, withudp-over-tcp-version=1written only for version 1: sing-box's default, version 2, is Chute's too. An enabledmultiplexis deliberately not carried over: sing-box negotiates smux / yamux / h2mux with its own padding, while Chute'smuxuses a framing of its own that a sing-box server cannot read, so the outbound is converted without multiplexing and a warning says so.detourbecomes an activeunderlying-proxy=reference; nested detours form multiple hops, while cycles and missing references fail closed. Awireguardendpoint'sdetouris kept as well, and its tunnel goes through that upstream's UDP relay; atailscaleendpoint with adetourother than direct is not imported, and references to it fail closed, with a warning. route.rule_set: aninlinerule set becomes a[Ruleset <tag>]section, andremoteandlocalrule sets become[Rule Provider]lines (type=http/type=file) withformat=sing-box-source. A rule set in a compiled binary format is skipped with a warning: point it at the source (.jsonor YAML) form of the same set. On this path the compiled format is.srs, detected fromformat: binaryor from a path ending in.srswhenformatis omitted;.mrsis sniffed only on the Clash rule-provider path, where mihomo infers the format from the extension the same way. On macOS the importer rewrites the URL to the source payload beside it where the publisher offers one; on iOS, Apple TV and Android it does not, because the sets published in binary are far past what those platforms will load anyway. Profiles imported by earlier versions wrote these rule sets asformat=mihomo-yamland loaded no rules from them; they now load without being imported again. A remote rule set is downloaded the way sing-box downloads it: through itsdownload_detour, itshttp_client(a tag fromhttp_clients, or an inline client) orroute.default_http_client, and, with none of these, through the default outbound (route.final). That route becomes the provider'spolicy=; one that resolves todirectadds nothing.- A sing-box duration keeps its unit:
update_interval: 3dis three days, andd,h,m,sandmsare all read. An interval whose unit did not parse fell back to the default of one day, which is not what a profile asking for7dwanted. - Route rules follow the
actionkey:route/bypassuse the named outbound,rejectbecomesREJECT(method: dropbecomesREJECT-DROP), andhijack-dns,sniffandresolveemit nothing because Chute controls those from[General]. Within a rule, matchers of the same kind are alternatives and different kinds must all match, as in sing-box:domain,domain_suffix,domain_keyword,domain_regex,ip_cidr,geoipandip_is_privateare one kind;portandport_rangeare another, as aresource_ip_cidrandsource_ip_is_private, andsource_portandsource_port_range; every other matcher is a kind of its own. A rule of one kind becomes one line per value, and a rule of several kinds becomes oneANDrule —{"network": "udp", "port": 443}becomesAND,((DEST-PORT,443),(PROTOCOL,udp)). Adomain_suffixwritten with a leading dot (.cn) becomesDOMAIN-SUFFIX,cn.type: logicalrules becomeAND/OR/NOT,invertwraps the whole rule inNOT, andport_range(a:b) andsource_port_rangebecome port ranges. Arule_setis one more condition of the rule wherever it appears, including inside atype: logicalor inverted rule (see Logical Rule); several tags on one rule are alternatives of each other. When one of those tags names a set that could not be imported, the tag is dropped with a notice and the rule keeps the rest — it then matches less. The whole rule is dropped only when every tag it names failed, or when therule_setsits inside atype: logicalor inverted rule, where dropping one alternative would change what the rest of the expression matches. A matcher with no Chute equivalent is dropped with a warning when another matcher of its kind remains (the rule then matches less); otherwise the whole rule is dropped, with a warning, rather than converted into a rule that matches more. - The DNS server that answers every name no DNS rule claims —
dns.final, or the first server whenfinalis not set — becomes the[General]DNS key for its kind, with itsdetourwritten as a#proxy=<policy>suffix and alocalserver assystem;proxy-dns-serveris not written. The other servers are reached through the[Host]entries thatdns.rulesbecome, with thelocalserver written asserver:systemand a plain, DoH, DoQ or DoH3 server'sdetouras a#proxy=<policy>suffix; a DoT server's[Host]entry cannot carry one, so its detour is dropped there with a warning. A DNS rule that routes a wholerule_setto one resolver becomes the set-keyed form,RULE-SET:<tag> = server:…— but only whenrule_setis the rule's only matcher, because sing-box requires matchers of different kinds to all match and a[Host]key holds one condition. A rule naming a set that could not be imported gets no entry, for the same reason its route rule would not.
Surge and Shadowrocket Profiles
A Surge or Shadowrocket profile is read directly, with no conversion step. Chute accepts each dialect's own spellings, so a pasted profile keeps working; these are the ones that differ from Chute's native keys or were added for compatibility:
- Subscription groups. Surge's
policy-path=<url>(withupdate-interval=andpolicy-regex-filter=) loads a group's members from a URL;include-all-proxies=trueandinclude-other-group=<name>add every proxy, or another group's members. Group parameters Chute does not use, such asno-alertoricon-url, are kept when the profile is saved. Shadowrocket'suse=truemarks a group whose listed names are subscriptions rather than proxies, and each name is read as a proxy provider. Shadowrocket'srandombecomes a random group. A group of a type Chute does not implement, such as Surge'sexternal, keeps its members and runs asselect, with a notice. See Policy Group. - Built-in policies. Shadowrocket's
PROXYstands for the policy selected in global proxy mode, unless the profile defines its ownProxy; each REJECT variant (REJECT-DROP,REJECT-TINYGIF,REJECT-DICT, …) behaves as its name says. See Built-in Policy. - Rules.
DST-PORT, port ranges,HOSTNAME-TYPEwithIPv4/IPv6/DOMAIN/SIMPLE,IP-ASN,AS…,FINAL,<policy>,dns-failed,notification-text=and[Ruleset <name>]sections — see Rule. Module rules come ahead of the profile's own rules, as in Surge. - General (Shadowrocket).
update-urlnames the profile's own update address, which is what Surge writes in the#!MANAGED-CONFIGheader; Chute reads either. A file carrying both keeps the header, since only the header can also carryintervalandstrict. Theupdate-urlline itself survives the save, so a Shadowrocket profile still saves as a Shadowrocket profile.close-if-proxy-chain-missingis kept, but Chute always refuses a chained policy whose upstream is missing, as itstruedoes. Shadowrocket's front proxy (前置代理), set only in its app, is written asglobal-underlying-proxyin Chute. - DNS. Shadowrocket's
direct-dns-server,proxy-dns-server,fallback-dns-server,dns-direct-system,dns-fallback-system(which appendssystemtofallback-dns-server, merging with one the profile also declares) andalways-ip-address, and[Host]lines of the formssid:<name> = server:…; Surge'sencrypted-dns-server,allow-dns-svcb,[Host] <domain> = script:<name>andserver:force-syslib. See DNS Server and Local DNS Mapping. - General.
proxy-test-urlandtest-timeout(the defaults for url-test, fallback and load-balance groups),udp-policy-not-supported-behaviour,encrypted-dns-skip-cert-verification, andhttp-api/http-api-web-dashboard, which map onto the external HTTP controller keys. See Misc Options. - Proxies. The
tuic-v5keyword, and a[WireGuard <name>]section written withpeer = (…). See Proxy Server and WireGuard Configuration. - HTTP.
header-replace-regex, thehttp-request/http-responseform of Body Rewrite,[Map Local]withdata-type=,status-code=andheader="Key: value|…", URL Rewritereject-array/reject-tinygif, and[MITM]h2,hostname-disabledandauto-quic-block. See Header Rewrite, Body Rewrite, Mock Response, URL Rewrite and HTTPS Decryption. - Scripts and modules.
cronexp=,type=genericandevent-name=in[Script];#!system_version,#!REQUIREMENT,#!IOS-ONLY/#!MACOS-ONLY/#!TVOS-ONLY, and%APPEND%/%INSERT%in a module's[General].#!system_versionand#!REQUIREMENTare only recorded: Chute reads them off the module, no app displays them, and neither gates whether the module loads. See JS Scripting and Module. - Sections Chute does not implement —
[Keystore],[Port Forwarding],[Testing],[DHCP],[Snell Server],[Panel],[Ponte],[MTProto]— load with one notice each and are saved back unchanged;[Tailscale <name>]is read as[Tailscale]. See Configuration.
Not available: a [Proxy] line naming a protocol Chute does not implement is not a configuration error. The policy is dropped with a notice, the line survives the save exactly as written, and references to that policy become dangling — they fail closed to REJECT at runtime rather than leaking to DIRECT. The protocols recognised this way are Surge's snell, external, h2-connect and trust-tunnel; Shadowrocket's hysteria (v1), juicity, sudoku, openconnect, mieru, brook, lua, http2, http3, relay and subscribe; and tailscale, which Chute configures once in the [Tailscale] section and uses through the built-in TAILSCALE policy. A [General] key with no Chute equivalent is likewise ignored with a notice while its line is kept as written.
Limitations
- Proxy chaining carries TCP and UDP. mihomo
dialer-proxyand sing-boxdetourbecomeunderlying-proxyreferences, Clashrelaygroups stay relay groups with the same hop order, and a provider's download route (mihomoproxy:, sing-boxdownload_detourorhttp_client) becomes itspolicy=. Cycles, missing references and a QUIC or WireGuard leg over an upstream without UDP are rejected and logged rather than sent directly; a Shadowsocks node withudp-over-tcpcarries its UDP over such an upstream as well. - Options with no Chute equivalent are dropped with a warning rather than silently: per-proxy
ip-version,interface-name,routing-mark,mptcp,packet-encoding,global-padding,authenticated-lengthandencryption, andudp-over-tcp/udp-over-tcp-versionon any proxy other thanss; per-groupdisable-udp,interface-nameandrouting-mark; and the General keysgeodata-mode,geox-url,find-process-mode,unified-delay,tproxy-port,redir-portand others. A group'siconis the exception: it is artwork, it changes no traffic, and it is dropped in silence. - Rule types with no equivalent are skipped:
IP-SUFFIX,SRC-IP-SUFFIX,SRC-GEOIP,SRC-IP-ASN,DSCP,UID,PROCESS-PATH-REGEX,IP-ACCEPTandREMATCH-NAME. A rule carrying mihomo'ssrcmodifier is skipped as well, rather than matching on the wrong endpoint. GEOSITEand theGEOIPcategories that are not ISO country codes name sets in mihomo's geo data files, which Chute does not carry.GEOIP,privateandGEOIP,lanbecomeRULE-SET,LAN, the built-in private-address set, on every platform — no download. The rest depend on where the import runs: on macOS the rule becomesRULE-SET,geosite-<tag>(orgeoip-<tag>) and a[Rule Provider]line is synthesized alongside it, pointing at the YAML payload published for that set, which you can repoint or delete like any other line. On iOS, Apple TV and Android the rule is dropped with a message saying so, because those sets are larger than the platform will convert — import the profile on a desktop to keep them. An ISO country code still goes to the bundled GeoIP database and needs no set at all.- Protocol details that Chute manages itself are not carried over: Hysteria2 port hopping (
ports), TUICheartbeat, AnyTLS session-pool tuning, WireGuardpeerslists (a single peer is configured) andworkers. - Transports Chute does not implement are reported instead of converted:
h2,httpobfuscation,httpupgrade, thev2ray-http-upgradeWebSocket variant, WebSocketmax-early-data, and XHTTPextra(XMUX / download-settings). A sing-box outbound whosetransport.typeishttpupgradeorquicis the exception: nothing is emitted for it and nothing is reported either, so check those outbounds by hand after the import. - Clash's operating
modeis a runtime switch in Chute, not a configuration key; a profile inglobalordirectmode converts to rule mode with a warning. - YAML is read with a standard parser, so anchors and the
<<merge key work. A value written as a multi-line scalar is folded onto one line, because a newline would split the configuration line it lands on. - A profile whose policy names are
{...}placeholders — what a subscription generator emits before its own substitution step — is named as a template: the import says so once, rather than only reporting every reference to a placeholder as an undefined policy.