apache/beam · error · UnsupportedOperationException
Read-only filesystem.
Error message
Read-only filesystem.
What it means
ClassLoaderFileSystem is a read-only filesystem backed by classloader resources; create() (any write operation) has no meaningful implementation and always throws UnsupportedOperationException('Read-only filesystem.').
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/io/ClassLoaderFileSystem.java:58
@SuppressWarnings({
"nullness" // TODO(https://github.com/apache/beam/issues/20497)
})
public class ClassLoaderFileSystem extends FileSystem<ClassLoaderFileSystem.ClassLoaderResourceId> {
public static final String SCHEMA = "classpath";
private static final String PREFIX = SCHEMA + "://";
ClassLoaderFileSystem() {}
@Override
protected List<MatchResult> match(List<String> specs) throws IOException {
throw new UnsupportedOperationException("Un-globbable filesystem.");
}
@Override
protected WritableByteChannel create(
ClassLoaderResourceId resourceId, CreateOptions createOptions) throws IOException {
throw new UnsupportedOperationException("Read-only filesystem.");
}
@Override
protected ReadableByteChannel open(ClassLoaderResourceId resourceId) throws IOException {
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream =
classLoader.getResourceAsStream(resourceId.path.substring(PREFIX.length()));
if (inputStream == null) {
throw new IOException(
"Unable to load "
+ resourceId.path
+ " with "
+ classLoader
+ " URL "
+ classLoader.getResource(resourceId.path.substring(PREFIX.length())));
}
return Channels.newChannel(inputStream);View on GitHub (pinned to 12126d8942)
Solutions
- Write to a real filesystem (local path, GCS, S3) instead of classpath://
- If data must ship with the app, write to a temp/working directory at runtime and keep only static reads on the classpath
- Check sink configuration so the output scheme is not classpath://
- For packaging artifacts, place resources at build time rather than writing at runtime
Example fix
// before
FileSystems.create(classpathResourceId, CreateOptions.defaults()); // throws
// after
ResourceId out = FileSystems.matchNewResource("/tmp/output.txt", false);
WritableByteChannel ch = FileSystems.create(out, CreateOptions.defaults()); Defensive patterns
Strategy: try-catch
Validate before calling
if ("classpath".equals(resourceId.getSchema())) {
throw new IllegalArgumentException("classpath filesystem is read-only");
} Type guard
static boolean isWritableDestination(ResourceId id) {
return !"classpath".equals(id.getSchema());
} Try / catch
try {
return FileSystems.create(resourceId, options);
} catch (UnsupportedOperationException e) {
// redirect to a writable filesystem
} Prevention
- Never configure sinks with classpath:// destinations
- Validate output schemas at pipeline construction time
- Treat the classpath filesystem strictly as a read-only source
When it happens
Trigger: Calling FileSystems.create with a classpath:// resource id, directly or via WriteFiles/TextIO.write to a classpath destination.
Common situations: Pipelines configured with output paths on the classpath schema; users assuming classpath resources are writable; accidental use of classpath URIs in a write sink.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Un-globbable filesystem.
- File spec %s not found
- Error matching file spec %s: status %s
- Failed to get metadata from MatchResult: %s.
- Failed to create directory:
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/04e32469d112d1e4.
Report an issue: GitHub.