apache/hadoop · error · UnsupportedOperationException
read only iterator
Error message
read only iterator
What it means
PathIterator returned by LocalDirAllocator.getAllLocalPathsToRead() is a read-only Iterator<Path>; its remove() is hard-coded to throw UnsupportedOperationException because the iterator only enumerates paths that exist across the configured working directories and supports no mutation.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/LocalDirAllocator.java:668
}
@Override
public Path next() {
final Path result = next;
try {
advance();
} catch (IOException ie) {
throw new RuntimeException("Can't check existence of " + next, ie);
}
if (result == null) {
throw new NoSuchElementException();
}
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException("read only iterator");
}
@Override
public Iterator<Path> iterator() {
return this;
}
}
/**
* Get all of the paths that currently exist in the working directories.
* @param pathStr the path underneath the roots
* @param conf the configuration to look up the roots in
* @return all of the paths that exist under any of the roots
* @throws IOException
*/
Iterable<Path> getAllLocalPathsToRead(String pathStr,
Configuration conf) throws IOException {
Context ctx = confChanged(conf);View on GitHub (pinned to 2add963021)
Solutions
- Do not call remove(); collect the paths into a List and filter the copy instead
- Delete files through FileSystem.delete(Path, boolean) on the specific returned path
Example fix
// before Iterator<Path> it = alloc.getAllLocalPathsToRead(p, conf).iterator(); it.next(); it.remove(); // after List<Path> hits = new ArrayList<>(); for (Path path : alloc.getAllLocalPathsToRead(p, conf)) hits.add(path); fs.delete(hits.get(0), false); // mutate via FileSystem, never via the iterator
Defensive patterns
Strategy: validation
Try / catch
try {
it.remove();
} catch (UnsupportedOperationException e) {
/* read-only iterator: mutate via FileSystem.delete instead */
} Prevention
- Treat LocalDirAllocator iterators as read-only
- Collect results into a List when you need to filter or mutate
- Delete files only via FileSystem.delete(Path, boolean)
When it happens
Trigger: Calling Iterator.remove() on the iterator from LocalDirAllocator#getAllLocalPathsToRead, either directly or indirectly through generic collection utilities/loops that invoke remove() while filtering.
Common situations: Code ported from mutable-collection iteration, custom filtering helpers that call it.remove() unconditionally after a predicate match.
Related errors
- Can't check existence of ${next}
- Remove is not supported for provided storage
- Remove is not supported.
- remove not supported.
- not implemented
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f958aa0648063447.
Report an issue: GitHub.