oracle/graal · error · UnsupportedOperationException

'{}' is unknown or read-only attribute

Error message

'{}' is unknown or read-only attribute

What it means

TruffleBasicFileAttributeView.setAttribute dispatches on the attribute name for lastModifiedTime/lastAccessTime/creationTime; if the switch falls through (unknown name) or setTimes throws IllegalArgumentException (bad value), it is converted to UnsupportedOperationException("'<attr>' is unknown or read-only attribute"). The view only supports the three basic timestamps.

Source

Thrown at espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/TruffleBasicFileAttributeView.java:101

        return map;
    }

    void setAttribute(String attribute, Object value)
                    throws IOException {
        try {
            switch (attribute) {
                case "lastModifiedTime":
                    setTimes((FileTime) value, null, null);
                    break;
                case "lastAccessTime":
                    setTimes(null, (FileTime) value, null);
                    break;
                case "creationTime":
                    setTimes(null, null, (FileTime) value);
                    break;
            }
        } catch (IllegalArgumentException x) {
            throw new UnsupportedOperationException("'" + attribute +
                            "' is unknown or read-only attribute");
        }
    }

    // region native methods

    private static native TruffleBasicFileAttributes readAttributes0(TrufflePath path, boolean followLinks) throws IOException;

    /*
     * Updates any or all of the file's last modified time, last access time, and create time
     * attributes. This method updates the file's timestamp attributes. -1 values are ignored e.g.
     * not set.
     */
    private static native void setTimes0(TrufflePath path, boolean followLinks, long lastModifiedTimeMillis, long lastAccessTimeMillis, long createTimeMillis) throws IOException;

    // endregion native methods
}

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Only set 'basic:lastModifiedTime', 'basic:lastAccessTime', 'basic:creationTime' with FileTime values.
  2. Filter out read-only attributes (size, isDirectory, fileKey, ...) before writing.
  3. Use the typed API: Files.setLastModifiedTime(path, time) instead of string-based setAttribute.

Example fix

// before
Files.setAttribute(p, "basic:isDirectory", false); // read-only -> throws

// after
Files.setLastModifiedTime(p, FileTime.fromMillis(System.currentTimeMillis()));
Defensive patterns

Strategy: validation

Validate before calling

static final Set<String> WRITABLE = Set.of("basic:lastModifiedTime", "basic:lastAccessTime", "basic:creationTime");
if (WRITABLE.contains(attr) && value instanceof FileTime) { Files.setAttribute(p, attr, value); }

Try / catch

try {
    Files.setAttribute(p, attr, value);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().contains("unknown or read-only attribute")) { /* skip read-only attr */ }
}

Prevention

When it happens

Trigger: Guest code calling Files.setAttribute(path, "basic:isDirectory", ...) or setting unsupported/read-only attributes (isRegularFile, isSymbolicLink, fileKey) through the Truffle filesystem provider; passing a non-FileTime to a time attribute.

Common situations: Generic metadata-copying utilities that iterate attributes and try to set each one; code assuming all attributes read via readAttributes can be written back.

Related errors


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