oracle/graal · error · UnsupportedOperationException

file attributes

Error message

file attributes: {attrs}

What it means

FileAttributeParser.parseWithDefault only understands the 'posix:permissions' FileAttribute; anything else (e.g. 'dos:readonly', 'basic:lastModifiedTime', or a custom attribute) throws UnsupportedOperationException listing the attributes. This backs file creation in the Truffle NIO provider where only POSIX permission masks can be translated.

Solutions

  1. Pass only PosixFilePermissions.asFileAttribute(...) style attributes.
  2. Set other metadata after creation via Files.setAttribute/Files.setLastModifiedTime, which are separate code paths.
  3. Branch on the provider/OS before attaching attributes.

Example fix

// before
Files.createFile(p, DosFileAttributeView...
// e.g. attribute "dos:readonly"

// after
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-r--r--");
Files.createFile(p, PosixFilePermissions.asFileAttribute(perms));
Files.setLastModifiedTime(p, FileTime.from(millis, TimeUnit.MILLISECONDS)); // set times separately
Defensive patterns

Strategy: validation

Validate before calling

static boolean isSupported(FileAttribute<?> a) {
    return "posix:permissions".equals(a.name());
}
// filter attrs before Files.createFile

Try / catch

try {
    Files.createFile(p, attrs);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().startsWith("file attributes")) {
        Files.createFile(p); // create bare, set metadata afterwards
    }
}

Prevention

When it happens

Trigger: Guest code calling Files.createFile/createDirectory/createSymbolicLink with FileAttribute<?> other than posix:permissions, e.g. Windows DOS attributes or NFS/basic timestamps, on the Truffle filesystem provider.

Common situations: Cross-platform code that sets dos:* attributes on Windows-targeted logic but runs on Espresso's POSIX-style Truffle FS; libraries constructing files with metadata attributes unconditionally.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/cbf843158a2c53ff. Report an issue: GitHub.

Appendix: source

Thrown at espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/FileAttributeParser.java:67

                    OTHERS_EXECUTE_VALUE;
    static final int ALL_READWRITE = OWNER_READ_VALUE |
                    OWNER_WRITE_VALUE |
                    GROUP_READ_VALUE |
                    GROUP_WRITE_VALUE |
                    OTHERS_READ_VALUE |
                    OTHERS_WRITE_VALUE;

    static int parseWithDefault(int defaultAttrs, FileAttribute<?>... attrs) {
        if (attrs == null || attrs.length == 0) {
            return defaultAttrs;
        }
        for (FileAttribute<?> attr : attrs) {
            if (attr.name().equals("posix:permissions")) {
                @SuppressWarnings("unchecked")
                Set<PosixFilePermission> perms = (Set<PosixFilePermission>) attr.value();
                return getMaskfromPosix(perms);
            } else {
                throw new UnsupportedOperationException("file attributes: " + Arrays.toString(attrs));
            }
        }
        throw new IllegalStateException("should not reach here");
    }

    private static int getMaskfromPosix(Set<PosixFilePermission> perms) {
        int mask = 0;
        for (PosixFilePermission perm : perms) {
            switch (perm) {
                case OWNER_READ:
                    mask |= OWNER_READ_VALUE;
                    break;
                case OWNER_WRITE:
                    mask |= OWNER_WRITE_VALUE;
                    break;
                case OWNER_EXECUTE:
                    mask |= OWNER_EXECUTE_VALUE;
                    break;

View on GitHub (pinned to a66e9ccd1d)