apache/hadoop · warning · UnsupportedOperationException

Remove is not supported for provided storage

Error message

Remove is not supported for provided storage

What it means

BlockAliasMap readers for HDFS provided storage expose an ImmutableIterator — a read-only view of provided block locations — whose remove() unconditionally throws UnsupportedOperationException. This is by design: the alias map is a source of truth about externally managed blocks and cannot be mutated through iteration.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/blockaliasmap/BlockAliasMap.java:45

import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.server.common.BlockAlias;

/**
 * An abstract class used to read and write block maps for provided blocks.
 */
@InterfaceAudience.Public
@InterfaceStability.Unstable
public abstract class BlockAliasMap<T extends BlockAlias> {

  /**
   * ImmutableIterator is an Iterator that does not support the remove
   * operation. This could inherit {@link java.util.Enumeration} but Iterator
   * is supported by more APIs and Enumeration's javadoc even suggests using
   * Iterator instead.
   */
  public abstract class ImmutableIterator implements Iterator<T> {
    public void remove() {
      throw new UnsupportedOperationException(
          "Remove is not supported for provided storage");
    }
  }

  /**
   * An abstract class that is used to read {@link BlockAlias}es
   * for provided blocks.
   */
  public static abstract class Reader<U extends BlockAlias>
      implements Iterable<U>, Closeable {

    /**
     * reader options.
     */
    public interface Options { }

    /**
     * @param ident block to resolve

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove the remove() call — filter with a predicate during iteration or collect items to keep into a new list
  2. If mutation is genuinely needed, maintain your own local Map<Long, FileRegion> copy instead of mutating the reader's view
  3. Audit third-party helpers you pass the iterator to for hidden remove() calls

Example fix

// before
Iterator<FileRegion> it = reader.iterator();
while (it.hasNext()) {
  if (stale(it.next())) it.remove(); // throws
}

// after
List<FileRegion> kept = new ArrayList<>();
for (FileRegion r : reader) {
  if (!stale(r)) kept.add(r);
}
Defensive patterns

Strategy: type-guard

Type guard

// Skip remove() on read-only alias map iterators
@SuppressWarnings("rawtypes")
static boolean isImmutableAliasMapIterator(Iterator<?> it) {
  return it instanceof BlockAliasMap.ImmutableIterator;
}

Prevention

When it happens

Trigger: Code iterating a BlockAliasMap.Reader (e.g., over FileRegions of provided blocks) calls iterator.remove() directly, or hands the iterator to a helper library/framework that calls remove() during traversal.

Common situations: Porting application code that previously iterated a mutable List<BlockAlias>; using collection utilities or reactive/stream frameworks that mutate the underlying source while iterating.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/57e4de9d38f8d62e. Report an issue: GitHub.