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

  1. Use the public FileSystem#getFileBlockLocations(FileStatus/Path, offset, len) API, which selects the correct op and falls back automatically
  2. If you maintain a fork adding an op, add a matching case to the switch in decodeResponse before the default branch
  3. 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

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


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