apache/hadoop · error · IllegalArgumentException
Unsupported Operation [{0}]
Error message
Unsupported Operation [{0}] What it means
After op resolves to a valid enum constant, ParametersProvider.get checks the provider's paramsDef map (ParametersProvider.java:80); if the operation has no registered parameter classes it throws IllegalArgumentException("Unsupported Operation [...]") → HTTP 400. The stock HttpFSParametersProvider registers every Operation constant, so in a vanilla server this never fires — it is the signature of a fork or embedded wsrs framework that added an enum constant without a PARAMS_DEF entry.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java:80
Map<String, String[]> queryString = request.getParameterMap();
String str = null;
if(queryString.containsKey(driverParam)) {
str = queryString.get(driverParam)[0];
}
if (str == null) {
throw new IllegalArgumentException(
MessageFormat.format("Missing Operation parameter [{0}]",
driverParam));
}
Enum op;
try {
op = Enum.valueOf(enumClass, StringUtils.toUpperCase(str));
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(
MessageFormat.format("Invalid Operation [{0}]", str));
}
if (!paramsDef.containsKey(op)) {
throw new IllegalArgumentException(
MessageFormat.format("Unsupported Operation [{0}]", op));
}
for (Class<Param<?>> paramClass : paramsDef.get(op)) {
Param<?> param = newParam(paramClass);
List<Param<?>> paramList = Lists.newArrayList();
String[] ps = queryString.get(param.getName());
if (ps != null) {
for (String p : ps) {
try {
param.parseParam(p);
}
catch (Exception ex) {
throw new IllegalArgumentException(ex.toString(), ex);
}
paramList.add(param);
param = newParam(paramClass);
}
} else {View on GitHub (pinned to 2add963021)
Solutions
- Register every operation in the provider's static init: PARAMS_DEF.put(Operation.YOUROP, new Class[]{ YourParam.class, ... }).
- If the operation must not be served, remove the enum constant so clients get the clearer 'Invalid Operation' message, or block it at the auth/filter layer.
- Add a unit test asserting paramsDef.keySet() equals all enum constants.
- Treat any occurrence as a server wiring bug and fix the provider, not the client.
Example fix
// before
public static final Map<Operation, Class<Param<?>>[]> PARAMS_DEF = new HashMap<>();
static { PARAMS_DEF.put(Operation.GETFILESTATUS, new Class[]{}); }
// Operation.MYOP exists in the enum but is never registered -> 400 Unsupported Operation
// after
static {
PARAMS_DEF.put(Operation.GETFILESTATUS, new Class[]{});
PARAMS_DEF.put(Operation.MYOP, new Class[]{ MyOpParam.class });
} Defensive patterns
Strategy: validation
Validate before calling
EnumSet<Op> registered = EnumSet.noneOf(Op.class);
registered.addAll(paramsDef.keySet());
if (!registered.equals(EnumSet.allOf(Op.class))) {
throw new IllegalStateException("paramsDef missing entries for: " + EnumSet.complementOf(registered));
} Type guard
static boolean isRegistered(Enum<?> op, Map<Enum, ?> paramsDef) {
return paramsDef.containsKey(op);
} Try / catch
try {
params = provider.get(request);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("Unsupported Operation")) {
LOG.error("provider wiring bug: operation not in paramsDef", ex);
return serverError();
}
throw ex;
} Prevention
- Every new Operation constant must ship with its PARAMS_DEF.put in the same commit.
- Unit test: paramsDef.keySet() == EnumSet.allOf(Operation.class).
- Treat 'Unsupported Operation' on a stock server as a fork bug, not a client error.
When it happens
Trigger: Adding Operation.MYOP (or a constant in a custom driver enum passed to your own ParametersProvider) without paramsDef.put(MYOP, new Class[]{...}); the first ?op=MYOP request parses the enum fine but fails the map lookup and throws.
Common situations: Vendored httpfs with custom operations; a PARAMS_DEF entry deleted while the enum constant stayed; copy-paste mistakes when wiring a new provider's static initializer.
Related errors
- Param class [{0}] does not have default constructor
- [{0}] = [{1}] exceeds max len [{2}]
- [{0}] = [{1}] must be "{2}"
- parameter [{0}] = [{1}] must be greater than zero
- parameter [{0}] = [{1}] must be greater than or equals zero
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/63fd013cf34258f0.
Report an issue: GitHub.