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

  1. 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).
  2. Verify the attribute name uses a supported Linux namespace prefix (user., security., system., trusted.); use user.* for unprivileged access.
  3. Confirm the filesystem supports xattrs (mount options, e.g. ext4 needs user_xattr; tmpfs/overlayfs may not); test with `getfattr -d <file>`.
  4. Run as root or gain needed capabilities when accessing trusted.* or security.* namespaces.
  5. 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

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


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/6fd53f7942be0588. Report an issue: GitHub.