{"record":{"id":"002b54cb46a7c40b","repo":"containerd/containerd","slug":"failed-to-get-capabilities-xattr-w","errorCode":null,"errorMessage":"failed to get capabilities xattr: %w","messagePattern":"failed to get capabilities xattr: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/archive/tar.go","lineNumber":646,"sourceCode":"\t\t\t\thdr.Typeflag = tar.TypeLink\n\t\t\t\thdr.Linkname = source\n\t\t\t\thdr.Size = 0\n\t\t\t} else {\n\t\t\t\tif k == fs.ChangeKindUnmodified {\n\t\t\t\t\tcw.inodeRefs[inode] = append(cw.inodeRefs[inode], name)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tcw.inodeSrc[inode] = name\n\t\t\t\tadditionalLinks = cw.inodeRefs[inode]\n\t\t\t\tdelete(cw.inodeRefs, inode)\n\t\t\t}\n\t\t} else if k == fs.ChangeKindUnmodified {\n\t\t\t// Nothing to write to diff\n\t\t\treturn nil\n\t\t}\n\n\t\tif capability, err := getxattr(source, \"security.capability\"); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get capabilities xattr: %w\", err)\n\t\t} else if len(capability) > 0 {\n\t\t\tif hdr.PAXRecords == nil {\n\t\t\t\thdr.PAXRecords = map[string]string{}\n\t\t\t}\n\t\t\thdr.PAXRecords[paxSchilyXattr+\"security.capability\"] = string(capability)\n\t\t}\n\n\t\tif err := cw.includeParents(hdr); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := cw.tw.WriteHeader(hdr); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write file header: %w\", err)\n\t\t}\n\n\t\tif hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {\n\t\t\tfile, err := open(source)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to open path: %v: %w\", source, err)","sourceCodeStart":628,"sourceCodeEnd":664,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/pkg/archive/tar.go#L628-L664","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check xattr readability\nif _, err := unix.Getxattr(path, \"security.capability\"); err != nil {\n    if err != unix.ENODATA && err != unix.ENOTSUP {\n        log.Warnf(\"xattr unreadable on %s: %v\", path, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := w.HandleChange(kind, path, fi); err != nil {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, unix.EACCES) {\n        return fmt.Errorf(\"need privileges to read %s: %w\", path, err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["archive","tar","xattr","permissions","filesystem"],"backgroundTag":"xattr-read-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}