apache/hadoop · warning · IOException
Unknown operation ${operation.name()}
Error message
Unknown operation ${operation.name()} What it means
Defensive default branch inside the JSON decoder used by WebHdfsFileSystem.getFileBlockLocations: the operation passed to the private helper must be GETFILEBLOCKLOCATIONS or GET_BLOCK_LOCATIONS, and any other GetOpParam.Op throws this IOException when decoding the response. The public API only ever passes those two ops (chosen by isServerHCFSCompatible, with automatic fallback at WebHdfsFileSystem.java:1934-1951), so reaching this branch means an internal caller, fork, or test passed an unhandled operation.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java:1972
private boolean isGetFileBlockLocationsException(RemoteException e) {
return e.getMessage() != null && e.getMessage().contains("Invalid value for webhdfs parameter")
&& e.getMessage().contains(GetOpParam.Op.GETFILEBLOCKLOCATIONS.toString());
}
private BlockLocation[] getFileBlockLocations(final GetOpParam.Op operation,
final Path p, final long offset, final long length) throws IOException {
return new FsPathResponseRunner<BlockLocation[]>(operation, p,
new OffsetParam(offset), new LengthParam(length)) {
@Override
BlockLocation[] decodeResponse(Map<?, ?> json) throws IOException {
switch (operation) {
case GETFILEBLOCKLOCATIONS:
return JsonUtilClient.toBlockLocationArray(json);
case GET_BLOCK_LOCATIONS:
return DFSUtilClient.locatedBlocks2Locations(JsonUtilClient.toLocatedBlocks(json));
default:
throw new IOException("Unknown operation " + operation.name());
}
}
}.run();
}
@Override
public Path getTrashRoot(Path path) {
statistics.incrementReadOps(1);
storageStatistics.incrementOpCounter(OpType.GET_TRASH_ROOT);
final HttpOpParam.Op op = GetOpParam.Op.GETTRASHROOT;
try {
String strTrashPath = new FsPathResponseRunner<String>(op, path) {
@Override
String decodeResponse(Map<?, ?> json) throws IOException {
return JsonUtilClient.getPath(json);
}
}.run();View on GitHub (pinned to 2add963021)
Solutions
- Use the public FileSystem#getFileBlockLocations(FileStatus/Path, offset, len) API, which selects the correct op and falls back automatically
- If you maintain a fork adding an op, add a matching case to the switch in decodeResponse before the default branch
- Check for mixed hadoop-hdfs-client versions on the classpath (mvn dependency:tree | grep hdfs-client) so the enum and the decoder come from the same jar
Example fix
// before: new op reaches decoder without a case -> default: throw
// after: handle it explicitly
switch (operation) {
case GETFILEBLOCKLOCATIONS:
return JsonUtilClient.toBlockLocationArray(json);
case GET_BLOCK_LOCATIONS:
return DFSUtilClient.locatedBlocks2Locations(JsonUtilClient.toLocatedBlocks(json));
case MY_NEW_OP:
return decodeMyNewOp(json);
default:
throw new IOException("Unknown operation " + operation.name());
} Defensive patterns
Strategy: validation
Validate before calling
private static final Set<GetOpParam.Op> BLOCK_LOCATIONS_OPS =
EnumSet.of(GetOpParam.Op.GETFILEBLOCKLOCATIONS,
GetOpParam.Op.GET_BLOCK_LOCATIONS);
if (!BLOCK_LOCATIONS_OPS.contains(operation)) {
throw new IllegalArgumentException(
"Unsupported block-locations op: " + operation);
} Type guard
static boolean isBlockLocationsOp(GetOpParam.Op op) {
return op == GetOpParam.Op.GETFILEBLOCKLOCATIONS
|| op == GetOpParam.Op.GET_BLOCK_LOCATIONS;
} Prevention
- Do not call the private getFileBlockLocations(op,...) runner; use the public FileSystem API
- When forking/adding GetOpParam.Op values, grep for every switch over the enum and extend them
- Pin a single hadoop-hdfs-client version across the classpath
When it happens
Trigger: Invoking the private getFileBlockLocations(operation, p, offset, length) with a GetOpParam.Op other than GETFILEBLOCKLOCATIONS/GET_BLOCK_LOCATIONS; typically a patched client that added a new op to GetOpParam.Op without extending this switch, or reflection-based tests calling the private method.
Common situations: Custom Hadoop forks that add block-location REST ops; unit tests driving internal runner classes; version-skewed jars where a new op enum value reaches an older WebHdfsFileSystem decode switch. Not reachable through the public FileSystem API.
Related errors
- Unable to support FSFileBlockLocationsLegacy because the fil
- FileMetadata not match key:" + key
- no such method
- url must be for a HTTP or HTTPS resource
- Path points to dir not a file
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/dd49d8e243b36614.
Report an issue: GitHub.