OneDrive 卡在"正在上传 X 个文件 (0%)"两周不动?我用一条日志揪出了真凶
OneDrive上传卡0%,经排查IO读取为0,发现是文件权限缺失导致引擎无法读取。使用 icacls /reset 命令修复权限后,同步恢复正常。
OneDrive上传卡0%,经排查IO读取为0,发现是文件权限缺失导致引擎无法读取。使用 icacls /reset 命令修复权限后,同步恢复正常。
排查耗时两周(断续),最后破案只花了一行日志。 如果你也在被"上传 0% 永远不动"折磨,而且 reset、解绑、重启全部无效——这篇文章就是为你写的。
任务栏 OneDrive 图标上挂着一行魔咒:
正在上传、137 文件、剩余 463.6 MB (0%)
这个数字两周纹丝不动。期间我做了所有"标准操作":
onedrive.exe /reset 重建同步数据库 —— 无效更诡异的是:新产生的文件能正常同步,删除文件、改文件名也正常。只有那 137 个文件像被冻结了一样。
还有一个线索当时被我忽略了:这些照片在电脑上双击打不开,提示"无权访问"。我当时以为是另一回事。
按常规思路我逐层排了一遍:
| 排查项 | 结果 |
|---|---|
| 未来时间戳的文件(相机时钟错乱) | 没有 |
| 路径超长 / 非法文件名 / 大小写冲突 | 没有 |
冲突副本(-LAPTOP-xxx 命名) | 只有几年前的旧文件 |
| 磁盘空间、防病毒、按流量计费 | 全部正常 |
| 同步数据库的"推迟重试队列" | 0 行,空的 |
uploads.txt 上传队列 | 0 行,空的 |
| 网络代理(Clash 挂着所有连接) | 换直连后依旧 |
| 微软认证端点、内容上传端点连通性 | 全部通畅 |
数据库层面甚至确认了:没有 hold、没有 reuploadNeeded、没有推迟项。本地引擎"认为"自己没有卡住的文件,但托盘显示 137 个。 两边对不上,这就是突破口。
折腾了两天数据库之后,我注意到 OneDrive 日志目录里有个纯文本的诊断日志(其他 .odl/.aodl 都是混淆二进制,不用浪费时间):
%LOCALAPPDATA%\Microsoft\OneDrive\logs\Personal\SyncDiagnostics.log
拉到最后一行,真凶就在那里:
StallErrorSummary = [Source:1 Reason:334 Context:0
ScopeID:d55ab6e3...
Files:137
Hits:3423
Extensions:heic;jpg;mov;mp4;png;webp;]
Files:137 —— 和托盘数字一字不差。
解读这行日志:
Reason:334 的错误**卡住(Stall)**了 137 个文件;Hits:3423:已经重试了 3423 次——进程运行了 6431 秒,相当于每 2 秒失败一次,无限循环;再看 IO 采样,证据链闭合:
\Process(OneDrive)\IO Read Bytes/sec → 恒为 0
上传的本质是"读文件 → 发网络"。引擎连文件都读不出来,当然 0%。而元数据操作(UploadBatch、EnumChanges)一直是 200 成功——所以删除、改名能同步。
结论:不是网络问题,不是队列问题,是引擎"读不到那 137 个文件的内容"。
想到"读不到",立刻联想到用户那句"打不开,提示无权访问"。用 icacls 对比了同一个文件夹里的两类文件:
icacls "D:\OneDrive\图片\本机照片\2026-08\某个打不开的照片.heic"
icacls "D:\OneDrive\图片\本机照片\2026-08\某个正常的照片.png"
结果判若云泥:
打不开的文件(卡住待上传的):
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
S-1-5-21-1411883608-...-1001:(I)(F) ← 一个"陌生"的本地账号
正常已同步的文件:
...(继承自文件夹)当前账号 SID:(M) Microsoft 账号 SID:(M) ✓
这批文件的 ACL(访问控制列表)里根本没有我当前 Windows 账号的 SID——它们是被一个旧的本地账号(SID 尾号 -1001)写入的,可能是某次 iPhone 导入工具在另一个账户上下文里跑出来的。
于是因果链完整了:
旧账号写入文件,ACL 只授权旧账号
↓
你的账号双击 → "无权访问"(打不开)
↓
OneDrive 引擎也是以你的账号运行的 → 同样读不到内容
↓
上传每次瞬间失败 → Reason:334 → 每 2 秒重试一次
↓
托盘永远停在 "137 文件 (0%)"
↓
reset / 解绑 / 重启全部无效——因为数据库根本没病,病在 NTFS 权限上
用数据库交叉验证也吻合:同步库里"已同步(fs=2)"的文件 ACL 全部正常,"待上传(fs=3)"的文件全部是孤儿 ACL,四个存在问题的月份文件夹无一例外。
icacls "D:\OneDrive" /reset /T /C /Q
参数解释:
/reset:丢弃文件上写坏的 ACL,重新从上级文件夹继承正常权限;/T:递归全部子目录;/C:遇到报错继续(不中断整个批处理);/Q:只报错误,不刷屏。我的库有 13.7 万个文件,跑了 7 分半,0 失败。修复后立刻验证:
IO Read Bytes/sec 瞬间从 0 变成持续 0.1~5 MB/s 的读取流——引擎终于读得动文件了,积压两周的队列开始真实消化。⚠️ 两个小坑:
- 在 Git Bash 里跑
icacls xxx /reset会被转义成路径报"无效参数"(exit 87),务必用 PowerShell 或 CMD;icacls的输出在中文系统是 GBK 编码,脚本里解析时注意decode('gbk')。
/reset 重建的是 OneDrive 自己的同步数据库,它从头到尾都认为"我没什么要重传的"——因为引擎每次尝试读文件内容都被 NTFS 拒绝,失败到连队列都懒得登记(推迟队列为空)。病根在文件系统的安全描述符上,任何在 OneDrive 应用层做的操作都摸不到它。
这次的教训排序:
SyncDiagnostics.log,再碰数据库。纯文本、最后一行、直接给出卡住文件数和重试次数,信息密度碾压一切二进制日志;Read Bytes/sec 恒 0 而元数据操作成功 ≈ 读不到文件内容 ≈ 查权限;icacls /reset 是 OneDrive 疑难杂症里被严重低估的招——它不在微软官方的"同步修复指南"里,但它治好了 reset 治好的病。如果你的 OneDrive 也卡 0%,按这个顺序 5 分钟定位:
# 1. 看卡住摘要(金钥匙)
Get-Content "$env:LOCALAPPDATA\Microsoft\OneDrive\logs\Personal\SyncDiagnostics.log" -Tail 5
# 2. 看引擎是否在读文件(连采几次,恒 0 = 读不到内容)
1..5 | ForEach-Object {
(Get-Counter "\Process(OneDrive)\IO Read Bytes/sec").CounterSamples[0].CookedValue
Start-Sleep 3
}
# 3. 对比正常/卡住文件的 ACL,找缺失的 SID
icacls "D:\OneDrive\某个正常的文件"
icacls "D:\OneDrive\某个卡住的文件"
whoami /user
# 4. 确认是孤儿 ACL 后,一键修复
icacls "D:\OneDrive" /reset /T /C /Q
修复后不需要重启 OneDrive,引擎下一个重试周期就会自动开始消化积压队列。祝你的百分比早日动起来。