uutils/coreutils · error · std::io::Error

failed to write whole buffer

Error message

failed to write whole buffer

What it means

`write_all_at` loops over `seek_write` until the whole buffer is written; if the Windows file write returns Ok(0) (zero bytes written), the function cannot make progress and throws `WriteZero` with this message. It mirrors std's `write_all` behavior for zero-length writes.

Solutions

  1. Check the destination file is opened with write (not just read) access and is a regular file
  2. Retry the copy; transient zero-byte writes can occur with some drivers/filesystems
  3. Verify the destination has free space and is not size-locked/quota-exhausted
  4. If it persists, file a bug with the exact offset and buffer size

Example fix

// before
let n = file.seek_write(buf, offset)?; // may return 0, loop forever
// after
let n = file.seek_write(buf, offset)?;
if n == 0 { return Err(io::Error::new(io::ErrorKind::WriteZero, "failed to write whole buffer")); }
Defensive patterns

Strategy: try-catch

Validate before calling

let md = std::fs::metadata(dest)?;
if !md.is_file() { return Err("destination is not a regular file"); }

Type guard

fn is_writable_regular_file(p: &Path) -> bool {
    std::fs::File::options().append(true).open(p).is_ok()
}

Try / catch

match write_all_at(&file, buf, offset) {
    Err(e) if e.kind() == std::io::ErrorKind::WriteZero => {
        eprintln!("short write at offset {offset}: {e}");
        // reopen destination with write access and retry
    }
    r => r?,
}

Prevention

When it happens

Trigger: A call to `FileExt::seek_write` returns 0 bytes written while copying data in `sparse_copy` (cp on Windows) or in the `write_all_at_writes_at_offset` test.

Common situations: Writing to a file that has been closed or opened without write access, writing past constraints on special/locked files, or a filesystem/driver reporting a zero-byte write on very large offsets during sparse copy.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of uutils/coreutils@92995feca2 (2026-09-20). Data as JSON: /api/errors/9899e14ecbc180bd. Report an issue: GitHub.

Appendix: source

Thrown at src/uu/cp/src/platform/windows.rs:100

            Ok(n) => total += n,
            Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    Ok(total)
}

/// Write the whole `buf` to `file` at `offset`, looping over partial writes.
///
/// The Windows-only `seek_write` has no `write_all`-style counterpart (unlike
/// the Unix `write_all_at`), so dropped tails on partial writes are handled
/// here. The `Interrupted` arm mirrors std's own write loops, although Windows
/// file I/O does not produce it.
fn write_all_at(file: &File, mut buf: &[u8], mut offset: u64) -> std::io::Result<()> {
    while !buf.is_empty() {
        match file.seek_write(buf, offset) {
            Ok(0) => {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::WriteZero,
                    "failed to write whole buffer",
                ));
            }
            Ok(n) => {
                buf = &buf[n..];
                offset += n as u64;
            }
            Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    Ok(())
}

/// Error from [`sparse_copy`], separating "the destination filesystem cannot
/// do sparse files" — which callers handle by falling back to a plain copy —
/// from real I/O failures.

View on GitHub (pinned to 92995feca2)