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

  1. Inspect the wrapped errno to identify the xattr failure cause
  2. Ensure the process can read the file (check permissions/ownership)
  3. Exclude capability-bearing or xattr-unsupported filesystems from the diff
  4. 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

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


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/002b54cb46a7c40b. Report an issue: GitHub.