TL;DR:把 rule-set URL 从配置里拎出来单独测试。Stash 更新失败时,最常见原因是把 GitHub 页面地址当成 raw 地址、YAML 缩进错、behavior 与文件格式不匹配,或旧缓存没有被替换。

Stash 的规则集更新看起来只是点一下刷新,但背后有三件事:下载规则文件、判断规则类型、写入本地缓存。任何一环失败,界面都可能只给出一个 update failed。排查要把「网络慢」和「格式错」分开。

排查表

项目应看到需要修正
URL打开后直接显示规则文本GitHub 仓库页面、404、HTML
behaviordomain / ipcidr / classical 与内容一致domain 文件写成 ipcidr
formatyaml、text、mrs、srs 与客户端支持一致二进制文件按文本解析
缓存刷新后时间变化一直停在旧时间
后台刷新前台与后台结果一致锁屏后失败、低电量模式失败

GitHub raw 地址先确认

如果规则源来自 GitHub,不要复制浏览器地址栏里的仓库文件页面。Stash 需要的是可直接下载的文本地址。打开后如果页面上有 GitHub 导航栏、按钮和样式,那就是错地址;正确结果应只有规则内容。

还要注意分支名变化。很多规则仓库从 master 切到 main 后,旧 URL 仍能打开页面,但 raw 地址会返回 404。把 URL 放到 Safari 或终端里看状态码,比在 Stash 里反复刷新更快。

YAML 层级比想象中更严格

rule-providers 下每个规则集都要有自己的名称、类型、地址和路径。缩进多两个空格或少两个空格,YAML 仍可能被读取,但语义已经变了。尤其是把 behavior 写到外层时,Stash 可能无法判断这份规则该按域名还是 IP 处理。

一份干净的检查顺序是:先保留一个 rule-set,刷新成功后再加第二个。不要一次导入十几个来源,否则你只能看到总失败,不知道是哪一个坏了。

缓存与后台刷新

iOS 和 macOS 都会限制后台网络。规则文件较大、GitHub raw 响应慢、设备进入低电量模式时,后台刷新可能失败。先在前台打开 Stash 手动刷新,成功后再观察后台任务。

如果你想减少格式转换带来的问题,可以选兼容 Clash / Singbox / V2Ray 的订阅,但仍要确认它给 Stash 的规则格式与当前配置一致。

用日志定位是哪一个规则集

Stash 配置里如果有多个 rule-set,不要靠界面总提示猜。先把规则集按名称排序,逐个刷新;能看到日志时,记录失败的 provider 名称、URL 和错误类型。网络错误、解析错误、写入错误对应的处理完全不同:网络错误看源站和跳转,解析错误看格式,写入错误看缓存或权限。

对于 GitHub raw,建议准备一个备用来源,但不要在同一配置里写两份同名规则。更稳的方式是保留主源,失败时手动切换到备用 URL,并记录切换时间。否则同名规则在缓存目录里互相覆盖,很难追踪当前到底加载了哪一份。

最小化测试配置

排查阶段可以复制当前配置,删到只剩一个 proxy、一个 proxy-group、一个 rule-set 和一条引用它的规则。最小配置能刷新,说明 Stash 本身和系统网络没问题;最小配置也失败,才需要继续看 App 权限、系统代理或源站响应。这个方法比反复重启设备更省时间。

规则内容也要抽样看

文本规则可以直接抽样检查。domain 类文件应主要是域名、后缀或 classical 写法;ipcidr 类文件应主要是 CIDR 网段。若一个 domain 文件里混入大量 IP,或者一个 ipcidr 文件里出现域名,说明来源、转换脚本或 behavior 至少有一处不一致。不要等到策略命中异常才回头看文件内容。

对于团队共享配置,最好在规则名里保留来源缩写,例如 github-domain-maincdn-ipcidr-backup。这样日志出现失败时,维护者一眼能知道该去哪个仓库或镜像检查,而不是在几十个相似 URL 之间翻找。规则改名后要同步改引用处,否则刷新成功也不会被实际规则命中。提交前用一个测试域名触发该规则,确认日志显示的是新名称。

相关阅读

FAQ

要不要把所有 rule-set 换成本地文件? 不必。常用规则保留远程更新更方便;只把长期不变、又经常超时的文件本地化。

MRS/SRS 文件能直接看内容吗? 不能像文本一样阅读。要确认客户端支持相应格式,并核对来源说明。

清缓存会丢配置吗? 通常只影响下载副本,不会删除主配置。操作前仍建议导出当前配置。