{"record":{"id":"6fd53f7942be0588","repo":"java-native-access/jna","slug":"errno-eno-xattrutil","errorCode":null,"errorMessage":"errno: {eno}","messagePattern":"errno: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java","lineNumber":222,"sourceCode":"\n    /**\n     * Get extended attribute value.\n     *\n     * @param path file path\n     * @param name extended attribute name\n     * @return extended attribute value\n     * @throws IOException on any error except <code>ERANGE</code> which handled internally\n     */\n    public static byte[] getXAttrBytes(String path, String name) throws IOException {\n        ssize_t retval;\n        byte[] valueMem;\n        int eno = 0;\n\n        do {\n            retval = XAttr.INSTANCE.getxattr(path, name, (byte[]) null, size_t.ZERO);\n            if (retval.longValue() < 0) {\n                eno = Native.getLastError();\n                throw new IOException(\"errno: \" + eno);\n            }\n\n            valueMem = new byte[retval.intValue()];\n            retval = XAttr.INSTANCE.getxattr(path, name, valueMem, new size_t(valueMem.length));\n            if (retval.longValue() < 0) {\n                eno = Native.getLastError();\n                if (eno != XAttr.ERANGE) {\n                    throw new IOException(\"errno: \" + eno);\n                }\n            }\n        } while (retval.longValue() < 0 && eno == XAttr.ERANGE);\n\n        return valueMem;\n    }\n\n    /**\n     * Get extended attribute value.\n     *","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java#L204-L240","documentation":"XAttrUtil.getXAttrBytes throws this IOException when the first getxattr call (called with a null buffer to query the attribute size) fails, i.e. returns -1. The message embeds the raw errno from Native.getLastError(). Typical errnos are ENODATA (attribute absent), EACCES/EPERM, E2BIG or ENOTSUP, so the developer must map the number to a cause themselves.","triggerScenarios":"Calling XAttrUtil.getXAttrBytes(path, name) on a path whose extended attribute `name` does not exist (ENODATA), on a file the caller lacks permission to read xattrs of (EACCES), on a filesystem without xattr support such as tmpfs or some NFS mounts (ENOTSUP/EOPNOTSUPP), or with an invalid attribute name (EINVAL/ERANGE for name too long).","commonSituations":"See trigger scenarios.","solutions":["Check the errno in the message: handle ENODATA as 'attribute does not exist' rather than a hard failure (catch IOException and compare nothing — instead first call listXAttr/getXAttrNames to verify the attribute exists).","Verify the attribute name uses a supported Linux namespace prefix (user., security., system., trusted.); use user.* for unprivileged access.","Confirm the filesystem supports xattrs (mount options, e.g. ext4 needs user_xattr; tmpfs/overlayfs may not); test with `getfattr -d <file>`.","Run as root or gain needed capabilities when accessing trusted.* or security.* namespaces.","Retry only on transient conditions; ERANGE during the sized read is handled internally by the library loop, so a failure here is a real non-ERANGE error."],"exampleFix":"// before\nbyte[] value = XAttrUtil.getXAttrBytes(path, \"user.comment\");\n// after\nList<String> names = XAttrUtil.getXAttrNames(path);\nif (!names.contains(\"user.comment\")) {\n    return null; // attribute absent, avoid ENODATA throw\n}\nbyte[] value = XAttrUtil.getXAttrBytes(path, \"user.comment\");","handlingStrategy":"try-catch","validationCode":"import java.nio.file.Files;\nimport java.nio.file.attribute.UserDefinedFileAttributeView;\n\nstatic boolean xattrReadable(java.nio.file.Path path, String name) {\n    try {\n        UserDefinedFileAttributeView view =\n            Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);\n        return view.list().contains(name);\n    } catch (Exception e) {\n        return false;\n    }\n}","typeGuard":"static boolean hasXattr(java.nio.file.Path path, String name) {\n    try {\n        return XAttrUtil.getXAttrNames(path).contains(name);\n    } catch (IOException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    byte[] value = XAttrUtil.getXAttrBytes(path, name);\n} catch (IOException e) {\n    // e.getMessage() is \"errno: N\"; N==61(ENODATA) means attribute absent\n    log.debug(\"xattr \" + name + \" unavailable: \" + e.getMessage());\n    value = defaultValue;\n}","preventionTips":["Check attribute existence with getXAttrNames before reading","Use user.* namespace prefixes for unprivileged code","Verify the filesystem supports xattrs (getfattr -d) before relying on them","Never assume symlinks share xattrs with their targets","Map errno numbers (ENODATA=61, EACCES=13, ENOTSUP=95) to friendly messages"],"tags":["io","linux","xattr","errno","filesystem"],"backgroundTag":"file-read-failed","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}