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

  1. Write to a real filesystem (local path, GCS, S3) instead of classpath://
  2. If data must ship with the app, write to a temp/working directory at runtime and keep only static reads on the classpath
  3. Check sink configuration so the output scheme is not classpath://
  4. 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

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/04e32469d112d1e4. Report an issue: GitHub.