k3s-io/k3s · error
error writing to %s: %v
Error message
error writing to %s: %v
What it means
Returned when writing an extracted regular file fails: the destination file was opened with O_RDWR|O_CREATE|O_TRUNC and either io.Copy(wf, tr) or a deferred wf.Close() returned an error (Close is promoted to the returned error if Copy succeeded). Typical errno causes are ENOSPC (disk or quota full), EACCES/EPERM (permissions, read-only mount), EDQUOT, or EIO on the underlying device.
Source
Thrown at pkg/untar/untar.go:88
// beforehand. Thus, don't check for errors; the next
// write will fail with the same error.
dir := filepath.Dir(abs)
if !madeDir[dir] {
if err := os.MkdirAll(filepath.Dir(abs), 0755); err != nil {
return err
}
madeDir[dir] = true
}
wf, err := os.OpenFile(abs, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode.Perm())
if err != nil {
return err
}
n, err := io.Copy(wf, tr)
if closeErr := wf.Close(); closeErr != nil && err == nil {
err = closeErr
}
if err != nil {
return fmt.Errorf("error writing to %s: %v", abs, err)
}
if n != f.Size {
return fmt.Errorf("only wrote %d bytes to %s; expected %d", n, abs, f.Size)
}
modTime := f.ModTime
if modTime.After(t0) {
// Clamp modtimes at system time. See
// golang.org/issue/19062 when clock on
// buildlet was behind the gitmirror server
// doing the git-archive.
modTime = t0
}
if !modTime.IsZero() {
if err := os.Chtimes(abs, modTime, modTime); err != nil && !loggedChtimesError {
// benign error. Gerrit doesn't even set the
// modtime in these, and we don't end up relying
// on it anywhere (the gomote push command relies
// on digests only), so this is a little pointlessView on GitHub (pinned to 6ba341e396)
Solutions
- Check free space and inodes on the destination: df -h <dir> and df -i <dir>
- Verify writability as the same user: touch <dir>/.wtest && rm <dir>/.wtest
- Fix mount options or ownership if the volume is read-only or permission-denied
- If ENOSPC, prune old data/images or enlarge the volume, then retry the extraction
Defensive patterns
Strategy: validation
Validate before calling
func CanExtractInto(dir string, needBytes int64) error {
var st syscall.Statfs_t
if err := syscall.Statfs(dir, &st); err != nil {
return err
}
if int64(st.Bavail)*int64(st.Bsize) < needBytes {
return fmt.Errorf("insufficient space in %s: need %d bytes", dir, needBytes)
}
f, err := os.CreateTemp(dir, ".probe-*")
if err != nil {
return fmt.Errorf("destination not writable: %w", err)
}
return os.Remove(f.Name())
} Try / catch
if err := untar.Untar(r, dir); err != nil {
var errno syscall.Errno
if errors.As(err, &errno) && (errno == syscall.ENOSPC || errno == syscall.EDQUOT) {
// free space / raise quota, then restart extraction from a clean dir
}
return err
} Prevention
- Check df -h and df -i on the target filesystem before large extractions
- Ensure the extracting uid owns or can write the destination directory
- Avoid extracting into read-only mounts or size-capped tmpfs
- Clean up partial extraction directories before retrying after a disk-full failure
When it happens
Trigger: untar.Untar into a directory on a full filesystem or one with a quota; destination on a read-only mount; running as a uid without write permission on the target path; disk I/O errors during extraction.
Common situations: Airgap/import workflows extracting into a small /var/lib or tmpfs that filled up after downloading the tarball; containers with read-only volumes or fsGroup/uid mismatches; long-lived nodes whose disk filled from old images or logs.
Related errors
- only wrote %d bytes to %s; expected %d
- tar error: %v
- tar contained invalid name error %q
- tar file entry %s contained unsupported file type %v
- failed %d link verifications
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/ed1e64bdd340cd79.
Report an issue: GitHub.