apache/hadoop · error · UnsupportedOperationException

does not support method

Error message

{} does not support method {}

What it means

methodNotSupported() is the shared helper both FileSystem and AbstractFileSystem use to reject optional operations the mounted implementation does not override: it builds the message from the implementation's canonical class name plus the calling method's name taken from stack-trace element index 2. Known callers include FileSystem.setQuota / setQuotaByStorageType and AbstractFileSystem.createMultipartUploader. Because the method name comes from a fixed stack depth, an extra wrapper frame between the API method and the helper can make the reported name misleading.

Solutions

  1. Read the exception's method name and canonical class to identify which optional operation and which implementation failed; if you use wrapper layers, verify the name against the actual call site since it is derived from stack depth.
  2. Route quota operations to HDFS (HdfsAdmin.setQuota / DistributedFileSystem) and multipart uploads to stores that implement them.
  3. Feature-detect at startup with a try/catch probe and remember the result per filesystem.
  4. For custom FileSystem subclasses, override the optional methods you support rather than relying on the default helper.

Example fix

// before
fs.setQuota(path, 1000, 1L << 30); // throws "...does not support method setQuota" on local FS

// after
if (fs instanceof DistributedFileSystem) {
  ((DistributedFileSystem) fs).setQuota(path, 1000, 1L << 30);
}
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean supportsQuotas(FileSystem fs, Path probe) {
  try {
    fs.setQuota(probe, Long.MAX_VALUE - 1, Long.MAX_VALUE - 1);
    fs.setQuota(probe, Long.MAX_VALUE, Long.MAX_VALUE); // reset
    return true;
  } catch (UnsupportedOperationException e) {
    return false;
  } catch (IOException e) {
    return true;
  }
}

Type guard

static boolean isHdfsBacked(FileSystem fs) {
  return fs instanceof DistributedFileSystem;
}

Try / catch

try {
  fs.setQuota(path, nsQuota, ssQuota);
} catch (UnsupportedOperationException e) {
  // optional op not implemented by this filesystem: skip or fail with context
  throw new IOException("Quotas unsupported on " + fs.getUri(), e);
}

Prevention

When it happens

Trigger: Calling setQuota or setQuotaByStorageType on a filesystem without quota support (local FS, most object stores) via the generic API; invoking createMultipartUploader on filesystems that have not implemented multipart upload (older versions before S3A/ABFS support); any custom FileSystem subclass that delegates unsupported optional methods to this helper.

Common situations: Quota-management tooling assumed HDFS and runs against file:// in tests; a committer or uploader library probes createMultipartUploader on whatever FS is configured; subclassed/wrapped FileSystems shift the stack frame so the error names the wrong method, sending debugging in the wrong direction.

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/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/94a5e183c75d6ca2. Report an issue: GitHub.

Appendix: source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/AbstractFileSystem.java:1671

  @InterfaceStability.Unstable
  public Path getEnclosingRoot(Path path) throws IOException {
    makeQualified(path);
    return makeQualified(new Path("/"));
  }

  /**
   * Helper method that throws an {@link UnsupportedOperationException} for the
   * current {@link FileSystem} method being called.
   */
  protected final void methodNotSupported() {
    // The order of the stacktrace elements is (from top to bottom):
    //   - java.lang.Thread.getStackTrace
    //   - org.apache.hadoop.fs.FileSystem.methodNotSupported
    //   - <the FileSystem method>
    // therefore, to find out the current method name, we use the element at
    // index 2.
    String name = Thread.currentThread().getStackTrace()[2].getMethodName();
    throw new UnsupportedOperationException(getClass().getCanonicalName() +
        " does not support method " + name);
  }
}

View on GitHub (pinned to 2add963021)