java-native-access/jna · error · IOException
errno: {eno}
Error message
errno: {eno} What it means
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.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java:222
/**
* Get extended attribute value.
*
* @param path file path
* @param name extended attribute name
* @return extended attribute value
* @throws IOException on any error except <code>ERANGE</code> which handled internally
*/
public static byte[] getXAttrBytes(String path, String name) throws IOException {
ssize_t retval;
byte[] valueMem;
int eno = 0;
do {
retval = XAttr.INSTANCE.getxattr(path, name, (byte[]) null, size_t.ZERO);
if (retval.longValue() < 0) {
eno = Native.getLastError();
throw new IOException("errno: " + eno);
}
valueMem = new byte[retval.intValue()];
retval = XAttr.INSTANCE.getxattr(path, name, valueMem, new size_t(valueMem.length));
if (retval.longValue() < 0) {
eno = Native.getLastError();
if (eno != XAttr.ERANGE) {
throw new IOException("errno: " + eno);
}
}
} while (retval.longValue() < 0 && eno == XAttr.ERANGE);
return valueMem;
}
/**
* Get extended attribute value.
*View on GitHub (pinned to d036ad9781)
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.
Example fix
// before
byte[] value = XAttrUtil.getXAttrBytes(path, "user.comment");
// after
List<String> names = XAttrUtil.getXAttrNames(path);
if (!names.contains("user.comment")) {
return null; // attribute absent, avoid ENODATA throw
}
byte[] value = XAttrUtil.getXAttrBytes(path, "user.comment"); Defensive patterns
Strategy: try-catch
Validate before calling
import java.nio.file.Files;
import java.nio.file.attribute.UserDefinedFileAttributeView;
static boolean xattrReadable(java.nio.file.Path path, String name) {
try {
UserDefinedFileAttributeView view =
Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
return view.list().contains(name);
} catch (Exception e) {
return false;
}
} Type guard
static boolean hasXattr(java.nio.file.Path path, String name) {
try {
return XAttrUtil.getXAttrNames(path).contains(name);
} catch (IOException e) {
return false;
}
} Try / catch
try {
byte[] value = XAttrUtil.getXAttrBytes(path, name);
} catch (IOException e) {
// e.getMessage() is "errno: N"; N==61(ENODATA) means attribute absent
log.debug("xattr " + name + " unavailable: " + e.getMessage());
value = defaultValue;
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: See trigger scenarios.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- No trash location found (define fileutils.trash to be the pa
- JNA temporary directory 'jnatmp' does not exist
- The following files could not be trashed: " + failed
- Size must greater than {size()}, requested {size}
- Can't open X Display
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/6fd53f7942be0588.
Report an issue: GitHub.