先建立一次可复现的请求

排查 Clash 连接失败时,先确定失败发生在哪一层:应用是否把请求交给客户端,内核是否完成规则匹配,节点地址是否能解析,以及出站连接是否建立。FlClash 是客户端,mihomo 是其使用的代理内核;界面错误、订阅下载错误与内核转发日志不一定出现在同一个位置。

进入客户端的「日志」页面,记录当前时间、运行模式、策略组选择和失败目标。菜单名称可能随客户端版本变化,应查找“内核日志”或“运行日志”,不要只看更新检查记录。接下来只刷新一个页面,或发送一次测试请求,避免后台应用的连接淹没目标记录。

  1. 确认当前使用的是 rule、global 还是 direct 模式。只有规则模式才适合排查自定义分流规则。
  2. 记录当前混合端口。下文统一以 127.0.0.1:7890 为示例,这不是所有客户端的固定默认值。
  3. 保留失败时间前后约 10 秒的日志,同时记录浏览器显示的错误。
  4. 每次只改变一项设置,然后对同一目标重复请求。不要同时切换节点、DNS 和 TUN。
curl -I -v --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 https://example.com/

这条命令显式使用本机 HTTP 代理入口,连接超时上限为 10 秒,总时长上限为 20 秒。Windows PowerShell 中可将命令名写为 curl.exe,避免旧环境中的同名别名。即使目标返回 403 或 405,也应先区分“收到 HTTP 响应”和“连接根本没有建立”。此测试验证代理入口,不代表 TUN 接管一定正常。

日志等级与每行字段怎么读

mihomo 的 log-level 支持 silent、error、warning、info、debug。通常先使用 info;需要查看更多解析和连接上下文时,临时改为 debug。客户端可能覆写订阅里的字段,因此应检查最终生效配置,而不是只修改下载下来的 YAML。

log-level: info
等级主要用途阅读重点
error严重错误配置加载、组件启动等失败;结合具体消息判断影响范围。
warning连接异常连接超时、解析异常等;单次警告不等于整个内核停止工作。
info日常定位启动信息、连接匹配和出站选择。
debug补充细节解析与内部处理信息;输出量大,排查后恢复。
silent关闭常规日志输出不适合采集故障现场。

下面是便于阅读的结构示意,不保证与每个 mihomo 版本逐字一致。图形客户端可能把时间、等级和消息拆成不同列。

time="2026-09-15T10:24:08+08:00" level=info msg="[TCP] 127.0.0.1:53124 --> example.com:443 match DomainSuffix(example.com) using 手动选择[节点A]"
  • time:用于关联同一次操作。先确认系统时区,不要将不同设备的时间直接混用。
  • [TCP] 或 [UDP]:表示传输协议。网页成功不代表 UDP 游戏或 QUIC 一定正常。
  • 127.0.0.1:53124:连接来源及临时源端口。这里的 53124 不是代理监听端口。
  • example.com:443:目标域名及端口。TUN 下也可能先看到目标 IP。
  • match:命中的规则类型与内容;using:所用策略及节点。

一行“命中规则并使用某节点”的记录,说明已经进行路由选择,不等于目标网站已经成功返回。还要继续查看相邻的连接错误和实际请求结果。

dial 超时:先判断正在连接谁

i/o timeout 与 context deadline exceeded

这两类信息表示某个操作在限定时间内没有完成,但单靠这几个词无法断言“节点失效”。先看它前面的操作对象:是 DNS 查询、到代理服务器的 TCP 连接,还是经代理访问目标的过程。错误链里出现的 IP 可能属于代理服务器、DNS 服务器或目标站点,三者的排查方向不同。

dial tcp 203.0.113.10:443: i/o timeout

上面的地址使用文档保留网段,仅用于说明格式。实际排查时,把日志里的地址与当前节点的 server、port 对照。如果它对应代理服务器,先确认本地网络到该服务器的连通性;如果是直连目标,则检查规则为何选择了 DIRECT,以及本地网络能否访问该目标。

  1. 同一节点测试两个不同目标。全部失败与只有一个站点失败,应分开处理。
  2. 保持规则和 DNS 不变,只替换节点。替换后恢复,问题更可能位于原节点或其链路。
  3. 保持节点不变,切换 Wi-Fi 与移动网络。仅某一网络失败时,再检查网络限制、路由与 IPv6 可达性。
  4. 若仅 UDP 请求失败,核对节点协议及服务端是否支持 UDP 转发,不要用 TCP 延迟结果代替 UDP 验证。

connection refused 与 network is unreachable

connection refused 通常表示连接被主动拒绝,例如端口没有服务监听,也可能由防火墙主动拒绝产生。若目标是 127.0.0.1:7890,先检查内核是否启动、实际端口是否变更;若目标是远端节点,则核对节点地址与端口。它与“等待到超时”不是同一种现象。

network is unreachable 更接近本机路由或地址族问题。例如日志尝试连接 IPv6 地址,而当前网络没有可用 IPv6 路由。应先检查路由与网络环境,再考虑调整 IPv6 相关配置。不要仅凭一次错误就全局关闭 IPv6。

DNS 解析失败:分清节点域名与访问域名

看到 no such host、DNS resolve failed 或带有 DNS 查询上下文的超时,先读清被查询的域名。代理服务器自身使用域名时,必须先解析它,才能建立代理连接;访问网站的域名则可能由本地 DNS、mihomo DNS 或代理链路处理,取决于入口与配置。

异常对象重点字段检查方向
节点服务器域名proxy-server-nameserver节点域名使用的解析器是否可达,是否存在解析依赖代理、代理又依赖解析的循环。
DoH 服务器域名default-nameserver用于解析 DNS 服务器域名的引导解析是否正常。
普通访问域名nameserver、nameserver-policy实际采用的解析器、分域策略及查询结果是否符合预期。
系统解析与内核不一致dns.enable、TUN DNS 劫持设置系统查询是否真正进入内核,应用是否使用自带 DoH。

no such host 常见于名称不存在等解析失败,但仍需结合上游响应确认。超时则表示没有及时拿到结果,不能据此认定域名不存在。命令 nslookup example.com 通常测试系统配置的 DNS,并不自动测试 mihomo 的 DNS。只有指定实际 DNS 监听地址和端口的工具,或内核自己的日志,才适合验证内核解析链路。

Fake-IP 模式下,应用可能收到 198.18.0.0/16 范围内的合成地址;这一范围常见于相关配置,但以实际 fake-ip-range 为准。看到这类地址不应立即判断为 DNS 污染。应检查域名映射、连接接管以及 fake-ip-filter 是否与当前应用需求一致。

不要把全部域名加入 fake-ip-filter 来消除日志里的合成地址。这会改变解析路径,却不能直接修复节点不可达、上游超时或 TUN 接管异常。

规则未命中:它往往不是一条报错

“规则未命中”通常是用户对分流结果的描述,不一定有对应的错误日志。mihomo 的规则按顺序匹配,前面的规则先匹配成功就不会继续执行后面的规则。末尾的 MATCH 是兜底规则,命中它属于正常路由行为,不表示内核解析规则失败。

mode: rule
rules:
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,PROXY

这是规则顺序片段,不是完整可运行配置;PROXY 必须是已有的策略组或出站名称。该片段让 example.com 及其子域名直连,其他请求交给 PROXY。若日志显示某个请求命中其他更靠前的规则,应调整顺序,而不是反复更换 DNS。

  • 先看模式:global 和 direct 模式不按普通规则列表进行预期的分流。
  • 再看元数据:只有目标 IP、没有域名时,域名规则可能无法按预期匹配。检查应用是否预先解析、Fake-IP 映射是否存在,以及是否需要适用的嗅探设置。
  • 检查规则来源:使用 RULE-SET 时,查看对应 rule-providers 是否加载成功,格式、路径和更新是否有错误。
  • 检查实际生效内容:订阅更新、覆写和客户端配置合并可能改变规则顺序。以运行配置为准。
  • 最后看策略组:命中代理策略组后,组内仍可能选中 DIRECT。组名包含“代理”不代表最终一定经过远端节点。

请求完全没有出现在连接记录中时,先验证流量入口。某些应用不遵循系统代理,需要单独设置代理或使用 TUN;部分请求也可能复用已有连接。关闭该应用后重新发起一次请求,比连续刷新旧连接更有辨识度。

端口占用与 TUN 启动失败

address already in use:检查监听者

典型信息是 listen tcp 127.0.0.1:7890: bind: address already in use。这表示监听地址与端口发生冲突,不是远端节点报错。常见原因是另一款代理客户端仍在后台运行,或者同一内核启动了两份。也要查看冲突的是混合端口、DNS 监听端口还是控制接口端口。

# Windows:查询 7890 端口,重点查看 LISTENING 行及其 PID
netstat -ano | findstr :7890

# macOS:查看 TCP 7890 的监听进程
lsof -nP -iTCP:7890 -sTCP:LISTEN

# Linux:查看 TCP 7890 的监听进程
ss -ltnp 'sport = :7890'

确认进程身份后,通过对应应用正常退出或调整监听端口。不要直接终止不认识的系统进程。如果将 mixed-port 从 7890 改为 7891,还要同步更新浏览器扩展、命令行环境变量和手动填写代理地址的应用。Linux 查看其他用户的进程信息时可能需要额外权限。

TUN 权限与路由问题:先确认启动阶段

TUN 依赖虚拟网络设备与系统权限。出现 operation not permitted、设备创建失败或路由添加失败时,应检查客户端的服务模式、系统授权和虚拟网卡状态,而不是先调整订阅节点。Windows 通常涉及管理员权限或已安装的服务;macOS、Linux 的具体授权方式取决于客户端实现。

若 TUN 启动成功,但目标请求没有进入内核,应检查 tun.auto-route、路由排除项、其他 VPN 和安全软件的影响。先退出其他会修改路由的客户端,再复测。不要为了排查长期关闭系统防火墙;需要验证拦截时,应针对具体程序、接口和端口检查规则。

TLS 与认证错误:连接建立后还要核对参数

如果日志已经进入 TLS 握手,却出现 x509: certificate has expired or is not yet valid,先核对系统日期、时间与时区,再检查证书有效期。若出现证书名称不匹配,则核对节点的 servername 或协议对应的 SNI 设置、服务器域名以及服务端证书。

EOF、connection reset by peer 和 TLS handshake timeout 的指向没有那么唯一。它们可能来自远端主动断开、传输参数不一致、中间网络干扰或握手未完成。需要结合协议、节点端口和发生阶段判断,不能把所有 EOF 都当成密码错误。

  • 核对协议类型、端口、密码或 UUID,以及传输层参数是否与服务端一致。
  • 使用 WebSocket 等传输时,检查路径与 Host 参数;参数名以当前协议配置为准。
  • 出现明确的认证失败信息时,优先重新核对凭据及订阅状态。
  • 不要将 skip-cert-verify: true 作为通用修复。跳过证书验证会降低连接身份验证能力,也不能修复端口或协议错误。

按固定顺序收敛问题,并保留复测结果

一段日志可能同时包含多个应用、多个节点和多次重试。最终结论应对应一条可复现的请求,而不是整屏里最醒目的红色文字。按下面的顺序处理,能减少在无关设置间来回切换。

  1. 启动层:配置是否成功加载,监听端口与 TUN 是否启动。启动失败时先处理语法、端口和权限。
  2. 入口层:显式代理请求能否进入内核。显式代理成功但原应用失败,转查系统代理、应用代理或 TUN。
  3. 路由层:查看目标、命中规则、策略组和最终节点,确认请求走向符合预期。
  4. 解析层:确认失败的是节点域名、DNS 服务域名还是访问域名,再检查对应解析路径。
  5. 连接层:区分超时、拒绝、无路由、TLS 和认证失败,每次只修改一个相关变量。
  6. 应用层:已经收到 HTTP 响应后,再排查网站状态、登录状态和应用协议,不再把所有失败归结为代理连接。

向维护者反馈时,附上客户端版本、内核版本、操作系统、触发步骤、运行模式、相关配置片段和同一次请求的日志。发布前移除订阅链接、访问令牌、密码、UUID 及私人域名;保留错误关键词、字段名、端口关系和时间顺序。若替换地址,应在不同日志行中保持同一对象使用同一代称。

恢复后,用相同入口、相同目标再测试一次,并记录是哪一项变更生效。最后把临时开启的 debug 恢复到日常等级。需要核对配置含义时,可继续查阅配置字段参考;首次设置代理入口与 TUN,可按入门指南逐项确认。