containerd/containerd · error

failed to set xattr %q on %s: %w

Error message

failed to set xattr %q on %s: %w

What it means

copyUpXAttrs writes each read attribute onto the destination via lsetxattrCreate and wraps failures as 'failed to set xattr'. The value was read fine from the source, but the destination filesystem or privilege level rejected the write.

Source

Thrown at pkg/archive/tar_unix.go:209

		if err == unix.ENOTSUP || err == sysx.ENODATA {
			return nil
		}
		return fmt.Errorf("failed to list xattrs on %s: %w", src, err)
	}
	for _, xattr := range xattrKeys {
		// Do not copy up trusted attributes
		if strings.HasPrefix(xattr, "trusted.") {
			continue
		}
		data, err := sysx.LGetxattr(src, xattr)
		if err != nil {
			if err == unix.ENOTSUP || err == sysx.ENODATA {
				continue
			}
			return fmt.Errorf("failed to get xattr %q on %s: %w", xattr, src, err)
		}
		if err := lsetxattrCreate(dst, xattr, data); err != nil {
			return fmt.Errorf("failed to set xattr %q on %s: %w", xattr, dst, err)
		}
	}

	return nil
}

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Check the wrapped errno: ENOTSUP => move destination to xattr-capable FS; EPERM => run privileged or drop protected namespaces.
  2. Filter to 'user.' namespace keys when destination privileges are limited.
  3. If ENOSPC, raise the filesystem EA limits or drop large/unused attributes (e.g. large security.ima entries).
  4. Match SELinux/AppArmor context handling between source and destination hosts.

Example fix

// before
for _, x := range keys { setXattr(dst, x, data) } // fails on security.selinux as non-root
// after
for _, x := range keys {
    if !strings.HasPrefix(x, "user.") { continue }
    setXattr(dst, x, data)
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: verify destination accepts xattrs before copy
if err := sysx.LSetxattr(dst, "user.probe", []byte{1}, 0); err != nil {
    if errors.Is(err, unix.ENOTSUP) {
        return fmt.Errorf("destination %s does not support xattrs", dst)
    }
}

Try / catch

if err := lsetxattrCreate(dst, key, data); err != nil {
    if errors.Is(err, unix.EPERM) {
        log.Warn("no privilege for xattr namespace", "key", key)
        return nil
    }
    return fmt.Errorf("failed to set xattr %q: %w", key, err)
}

Prevention

When it happens

Trigger: lsetxattrCreate(dst, key, data) failing with ENOTSUP (destination FS lacks xattrs for that namespace), EPERM (unprivileged write to security.*/system.*), ENOSPC (xattr size/EA block limits exceeded), or EDQUOT.

Common situations: Copying layers onto tmpfs/vfat/9p mounts without user.* xattr support; copying security.selinux into a container without privileges; exceeding destination inode EA space when many/large xattrs are present.

Related errors


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