containerd/containerd · error
failed to write file header: %w
Error message
failed to write file header: %w
What it means
After computing the header and writing parent directories, HandleChange writes the tar header with cw.tw.WriteHeader. Any tar writer failure (underlying writer error, write-after-close, out-of-space on the sink) is wrapped with this message so the caller knows header serialization failed rather than file content copy.
Source
Thrown at pkg/archive/tar.go:658
} else if k == fs.ChangeKindUnmodified {
// Nothing to write to diff
return nil
}
if capability, err := getxattr(source, "security.capability"); err != nil {
return fmt.Errorf("failed to get capabilities xattr: %w", err)
} else if len(capability) > 0 {
if hdr.PAXRecords == nil {
hdr.PAXRecords = map[string]string{}
}
hdr.PAXRecords[paxSchilyXattr+"security.capability"] = string(capability)
}
if err := cw.includeParents(hdr); err != nil {
return err
}
if err := cw.tw.WriteHeader(hdr); err != nil {
return fmt.Errorf("failed to write file header: %w", err)
}
if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {
file, err := open(source)
if err != nil {
return fmt.Errorf("failed to open path: %v: %w", source, err)
}
defer file.Close()
n, err := copyBuffered(context.TODO(), cw.tw, file)
if err != nil {
return fmt.Errorf("failed to copy: %v: %w", source, err)
}
if n != hdr.Size {
return errors.New("short write copying file")
}
}
View on GitHub (pinned to 4246446a2b)
Solutions
- Check the wrapped inner error from the tar writer
- Ensure the destination writer stays open until ChangeWriter.Close completes
- Do not call Close concurrently with HandleChange
- Check available disk space or downstream transport health
Example fix
// before
pr, pw := io.Pipe()
go func(){ cw.Close(); pw.Close() }() // closes early
// after
go func(){ defer pw.Close(); if err := cw.Close(); err != nil { log.Error(err) } }() Defensive patterns
Strategy: try-catch
Try / catch
pr, pw := io.Pipe()
done := make(chan error, 1)
go func() {
defer close(done)
_, err := io.Copy(consumer, pr)
if err != nil { pr.CloseWithError(err) } // propagate sink errors upstream
}()
if err := w.HandleChange(kind, path, fi); err != nil {
return fmt.Errorf("tar header write failed for %s: %w", path, err)
} Prevention
- Never Close the ChangeWriter while HandleChange is running
- Keep the tar consumer reading for the lifetime of the diff
- Check disk space / transport health before large diffs
- Surface errors from the reading side back into the pipe
When it happens
Trigger: tw.WriteHeader returns an error — typically the underlying io.Writer of the tar writer failed (pipe closed, disk full, connection broken), or WriteHeader is invoked on a tar.Writer already closed by a prior error.
Common situations: Consumer of the tar stream closed the pipe early; disk full while streaming to a file; concurrent Close of the ChangeWriter while HandleChange is still processing changes.
Related errors
- failed to close tar writer: %w
- failed to copy: %v: %w
- invalid archive
- short write copying file
- failed to copy to tar: %w
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/8976bf291708ec41.
Report an issue: GitHub.