Technology · PRACTICAL GUIDE
curl error 18? Prove the missing bytes before retrying or resuming
CURLE_PARTIAL_FILE means curl received a size that did not match the size the peer announced. Preserve the partial artifact, response headers and trace; then isolate framing, protocol and intermediary behavior before a safe restart or validator-bound resume.

curl error 18 is evidence of a transfer-size mismatch, not a diagnosis of one universal network problem. The curl project defines CURLE_PARTIAL_FILE as a transfer shorter or larger than the size previously reported.
Do not overwrite the first partial file or turn on retries immediately. Capture the response framing, received bytes and representation identity so a server, proxy, protocol or client-path change can be tested rather than guessed.
1. Freeze the first failure
Move the partial output to a uniquely named evidence file instead of rerunning into the same path. Record its byte count and digest. Save curl version and feature output, the exact command with secrets removed, start and end times, exit code, remote URL, proxy path and whether a wrapper or CI runner invoked curl.
Run one evidence capture to a new file. Store response headers separately and enable a timestamped trace with sensitive headers redacted. Do not publish Authorization, Cookie, signed query strings or client certificates. The first trace is valuable because a retry may hit another backend or a new representation.
2. Read the framing before blaming the network
For HTTP/1.1, classify the response by framing. If Transfer-Encoding ends in chunked, completion requires the last zero-size chunk. If there is no Transfer-Encoding and Content-Length is valid, that decimal number is the expected body length. A close before that count is incomplete under RFC 9112.
Keep content coding separate from transfer coding. gzip or br describes representation encoding; chunked describes message framing. Changing Accept-Encoding or forcing HTTP/1.0 may alter server behavior, so it can isolate a branch, but it does not repair a wrong length, truncated origin process or broken intermediary by itself.
3. Compare one variable at a time
Repeat to a new output while changing only one boundary: direct origin versus proxy or CDN, IPv4 versus IPv6 when both are valid, HTTP/1.1 versus HTTP/2 or HTTP/3, or compressed versus identity representation. Record status, effective URL, protocol, declared length, downloaded bytes, exit code and digest for every run.
A success under one path does not prove the other path safe. If the origin succeeds and the proxy truncates, preserve both traces for the intermediary owner. If every path ends at the same byte, inspect the origin application, upstream timeouts, generated Content-Length and storage read errors.
4. Decide whether the partial bytes are usable
Do not accept a 200 status alone. Require curl exit 0, the expected byte count or framing completion, and a representation-level integrity signal such as a publisher checksum, signature, archive test or application parser. An HTML error body saved with a binary filename is not a successful download.
For API calls, also validate the response schema and the intended side effect. Retrying a non-idempotent POST can duplicate work even if the response was truncated after the server committed it. Check an idempotency key, transaction identifier or status endpoint before repeating the request.
5. Resume only under a proven contract
A partial file can be resumed only when the server supports the required byte range and the remote representation is unchanged. Preserve ETag or Last-Modified, use a conditional range request when the workflow supports it, and verify that the server returns the expected partial status and range rather than a new full body.
If validators are absent, weak or changed, start from a fresh destination. Never append blindly. Close the incident only when a clean run passes exit code, framing, byte count and integrity checks, and when the failing path has either been repaired or explicitly removed from production.
