containerd/containerd · error
failed to get capabilities xattr: %w
Error message
failed to get capabilities xattr: %w
What it means
Before writing a regular file header, HandleChange reads the security.capability xattr to preserve file capabilities (like setcap'd binaries) in the archive via PAX records. If getxattr returns an error other than ENODATA, archive creation fails with this wrapped error so capabilities are never silently dropped.
Source
Thrown at pkg/archive/tar.go:646
hdr.Typeflag = tar.TypeLink
hdr.Linkname = source
hdr.Size = 0
} else {
if k == fs.ChangeKindUnmodified {
cw.inodeRefs[inode] = append(cw.inodeRefs[inode], name)
return nil
}
cw.inodeSrc[inode] = name
additionalLinks = cw.inodeRefs[inode]
delete(cw.inodeRefs, inode)
}
} 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)View on GitHub (pinned to 4246446a2b)
Solutions
- Inspect the wrapped errno to identify the xattr failure cause
- Ensure the process can read the file (check permissions/ownership)
- Exclude capability-bearing or xattr-unsupported filesystems from the diff
- If the FS genuinely lacks xattr support, mount or copy files to a filesystem that supports them before diffing
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check xattr readability
if _, err := unix.Getxattr(path, "security.capability"); err != nil {
if err != unix.ENODATA && err != unix.ENOTSUP {
log.Warnf("xattr unreadable on %s: %v", path, err)
}
} Try / catch
if err := w.HandleChange(kind, path, fi); err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) && errors.Is(pathErr.Err, unix.EACCES) {
return fmt.Errorf("need privileges to read %s: %w", path, err)
}
return err
} Prevention
- Run diff/commit operations with enough privilege to read all file metadata
- Avoid diffing FUSE/NFS volumes that reject security.* xattrs, or copy data first
- Check filesystem xattr support before building images from it
When it happens
Trigger: getxattr(path, "security.capability") on the changed file returns a real error — filesystem without xattr support returning unexpected errors, permission denied on the file, or a network/FUSE filesystem rejecting xattr reads.
Common situations: Building images on overlayfs or tmpfs setups where xattr lookups behave unexpectedly; archiving files with restrictive permissions as unprivileged user; FUSE/network mounts (NFS, CIFS) that don't support security.* xattrs.
Related errors
- failed to open path: %v: %w
- failed to make path relative: %w
- failed to set device headers: %w
- failed to copy: %v: %w
- invalid archive
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/002b54cb46a7c40b.
Report an issue: GitHub.