科技 · 实用指南
curl 错误 18?重试或续传前先证明缺失字节
CURLE_PARTIAL_FILE 表示实际收到的大小与对端先前声明的大小不一致。先保留残缺文件、响应头和跟踪,再区分消息分帧、协议与中间层,最后决定全新重传或绑定验证器的续传。

curl 错误 18 是传输大小不一致的证据,不是某一种网络故障的最终诊断。curl 项目把 CURLE_PARTIAL_FILE 定义为实际传输比先前报告的大小更短或更长。
不要立刻覆盖第一次残缺文件,也不要先开启自动重试。先记录响应分帧、收到的字节以及表示对象身份,再逐一验证服务器、代理、协议或客户端路径。
1. 冻结第一次失败证据
把残缺输出移到唯一命名的证据文件,不要直接覆盖;记录字节数和摘要。同时保存 curl 版本与功能、去除秘密后的命令、起止时间、退出码、远端 URL、代理路径以及是否由包装器或 CI 调用。
只做一次新的证据采集:响应头单独保存,时间戳跟踪中删除 Authorization、Cookie、签名查询和客户端证书。重试可能命中不同后端或新对象,所以第一次跟踪尤其重要。
2. 先读分帧,再判断网络
HTTP/1.1 中,若最终 Transfer-Encoding 为 chunked,必须读到零长度终止块;若没有 Transfer-Encoding 且 Content-Length 有效,该十进制值就是预期正文长度。连接在达到该值前关闭,RFC 9112 将其视为不完整。
内容编码与传输编码必须分开。gzip 或 br 描述表示对象编码,chunked 描述消息分帧。改变 Accept-Encoding 或强制 HTTP/1.0 只能用于隔离分支,不能自动修复错误长度、源程序截断或中间层故障。
3. 每次只改变一个边界
每次写入新的输出,只改变一个条件:直连源站与代理/CDN、有效的 IPv4 与 IPv6、HTTP/1.1 与 HTTP/2/3、压缩与 identity。逐次记录状态、最终 URL、协议、声明长度、下载字节、退出码和摘要。
某一路径成功并不证明另一路径安全。源站成功而代理截断时,保留两份跟踪交给中间层负责人;所有路径都停在同一字节时,应检查源应用、上游超时、Content-Length 生成和存储读取错误。
4. 判断残缺字节是否可用
不能只看 200 状态。至少要求 curl 退出码为 0、字节数或分帧完成,并通过发布方校验和、签名、压缩包测试或应用解析器等对象级完整性信号。二进制文件名下的 HTML 错误页仍是失败。
API 还要验证响应结构和预期副作用。非幂等 POST 可能已在服务器提交,只是响应被截断;重试前先查幂等键、事务编号或状态接口。
5. 只在契约明确时续传
只有服务器支持所需字节范围且远端表示对象未变化时才能续传。保存 ETag 或 Last-Modified,在流程支持时使用条件范围请求,并确认服务器返回预期部分状态和范围,而不是新的完整正文。
验证器缺失、过弱或已变化时,必须写入全新目标,绝不盲目追加。只有退出码、分帧、字节数和完整性全部通过,并且故障路径已修复或移出生产,才算关闭问题。
