apache/beam · error · UnsupportedOperationException

Un-globbable filesystem.

Error message

Un-globbable filesystem.

What it means

ClassLoaderFileSystem exposes classpath resources as a read-only Beam filesystem, but classpath resources are not enumerable as paths, so glob matching and listing cannot be performed. Its match implementation always throws UnsupportedOperationException('Un-globbable filesystem.').

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/io/ClassLoaderFileSystem.java:52

import org.apache.beam.sdk.io.fs.ResourceId;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.collect.ImmutableList;
import org.checkerframework.checker.nullness.qual.Nullable;

/** A read-only {@link FileSystem} implementation looking up resources using a ClassLoader. */
@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

View on GitHub (pinned to 12126d8942)

Solutions

  1. Do not glob classpath:// paths; reference exact resource paths via open/read instead
  2. Expand the pattern yourself against known resource names, then open each exact path
  3. Copy resources from the classpath to a real (local/GCS) filesystem and use that schema for globbing
  4. Use FileSystems.open with a fully specified resource id rather than match

Example fix

// before
FileSystems.match(java.util.Collections.singletonList("classpath://data/*.json")); // throws
// after
ReadableByteChannel ch = FileSystems.open(
    FileSystems.matchNewResource("classpath://data/exact-file.json", false));
Defensive patterns

Strategy: try-catch

Validate before calling

if (spec.startsWith("classpath://") && spec.contains("*")) {
  throw new IllegalArgumentException("cannot glob classpath resources");
}

Type guard

static boolean isGlobbable(String spec) {
  return !spec.startsWith("classpath://");
}

Try / catch

try {
  return FileSystems.match(specs);
} catch (UnsupportedOperationException e) {
  // fall back to exact resource paths
}

Prevention

When it happens

Trigger: Calling FileSystems.match (directly or via IO expansion) on a classpath:// spec, especially with wildcards; metadata resolution against classpath URLs.

Common situations: Users pointing Beam IO sources at classpath:// paths expecting wildcard expansion; pipelines configured to read inputs via classpath URIs with glob patterns.

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/057888bdad5bdb99. Report an issue: GitHub.