Watch at EaseStories. Answers. Perspective.

Technology · PRACTICAL GUIDE

curl error 23: diagnose the output consumer before retrying the transfer

Error 23 means curl could not write received data to its local destination. Preserve stderr and every pipeline status, identify whether the consumer is a file, pipe, terminal or callback, repair that writer, and verify the final bytes before calling the transfer complete.

Original diagram mapping curl output to file, pipe, terminal and callback consumers, each with its own failure evidence.
Original illustration: error 23 identifies a failed local writer; name the output consumer before choosing a repair. Watch at Ease

curl exit code 23 is a local write failure, not a diagnosis of the network path. The useful question is which process or filesystem owned the next write when curl stopped. Capture curl stderr and the status of every pipeline stage, name the actual output sink, reproduce its write contract, fix that sink, and accept the result only after a complete byte count or trusted digest check.

1. Preserve the first failure before retrying

Run the smallest equivalent command without hiding stderr. For a direct file, record the command, destination path, curl exit code and the first write error. For a pipeline, capture Bash PIPESTATUS immediately after the pipeline because the visible status can otherwise come from the final command; enable pipefail when a nonzero upstream status must fail the whole step.

Do not start by adding retries, redirecting stderr to /dev/null or changing TLS options. curl documents code 23 as a failure to write received data to a local filesystem or similar destination. A retry cannot create a missing parent directory, free blocks or inodes, reopen an intentionally closed pipe, or make a callback return the byte count curl supplied.

2. Name the consumer that owned the failed write

If -o or --output names a file, inspect that exact path: parent existence, permissions, free blocks, free inodes, quotas, mount state and namespace. If stdout is piped, the next process is the consumer; determine whether it exited intentionally after a prefix, crashed, or rejected data. If output goes to a terminal, check the terminal writer and any pager. In libcurl, inspect the write callback and its return value.

The callback contract is exact: the write function receives a block and must report the number of bytes handled. A short or failed return aborts the transfer with CURLE_WRITE_ERROR. That makes callback telemetry—requested bytes, returned bytes and application error—part of the same incident record as filesystem and pipeline evidence.

3. Reproduce the sink, not the remote request

Use a harmless known input to test the local consumer separately. In bounded Linux tests with curl 8.5.0, writing a local file URL to /dev/full returned 23; writing to a path whose parent did not exist returned 23; piping the stream to head -c 1 made head exit successfully while curl returned 23 because the reader closed early. A full stream into sha256sum returned zero from both stages.

An early-closing command such as head can be intentional when only a prefix is required. Record that as an explicit partial-read contract rather than relabeling it a complete download. For installers, archives and data imports, a partial read is not acceptable: keep the pipeline failing until the complete consumer contract and artifact check pass.

4. Repair the owner and define acceptance evidence

Repair the branch you proved: create the correct parent with deliberate ownership, free or extend the constrained filesystem, restore a writable mount, fix the downstream program, avoid a prefix-only consumer for a complete transfer, or correct the callback so it durably handles and reports every byte. Repeat the same evidence capture after the change.

Acceptance needs more than the absence of a message. Require curl and every required consumer to return the intended status; confirm the destination exists in the expected namespace; compare byte length when authoritative; and verify a publisher-provided digest or signature when available. Keep the original stderr, statuses, destination identity and final validation together so a quiet but truncated artifact cannot pass.

Original diagram showing capture, identify, reproduce, repair and verify steps for curl error 23.
Original experimental illustration: preserve both producer and consumer status, repair the actual sink, then verify complete bytes or a trusted digest. Watch at Ease