apache/hadoop · error · IllegalArgumentException

{str} is not a valid PUT operation.

Error message

{str} is not a valid PUT operation.

What it means

PutOpParam parses the 'op' query parameter of WebHDFS/HttpFS PUT requests against the Op enum in PutOpParam.java:25-63: CREATE, MKDIRS, CREATESYMLINK, RENAME, SETREPLICATION, SETOWNER, SETPERMISSION, SETTIMES, RENEWDELEGATIONTOKEN, CANCELDELEGATIONTOKEN, MODIFYACLENTRIES, REMOVEACLENTRIES, REMOVEDEFAULTACL, REMOVEACL, SATISFYSTORAGEPOLICY, SETACL, SETXATTR, REMOVEXATTR, ENABLEECPOLICY, DISABLEECPOLICY, SETECPOLICY, ALLOWSNAPSHOT, DISALLOWSNAPSHOT, CREATESNAPSHOT, RENAMESNAPSHOT, SETSTORAGEPOLICY, SETQUOTA, SETQUOTABYSTORAGETYPE, NULL. Parsing is case-insensitive; any other value throws this IllegalArgumentException (HTTP 400).

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/resources/PutOpParam.java:125

      return NAME + "=" + this;
    }
  }

  private static final Domain<Op> DOMAIN = new Domain<>(NAME, Op.class);

  /**
   * Constructor.
   * @param str a string representation of the parameter value.
   */
  public PutOpParam(final String str) {
    super(DOMAIN, getOp(str));
  }

  private static Op getOp(String str) {
    try {
      return DOMAIN.parse(str);
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(str + " is not a valid " + Type.PUT
          + " operation.");
    }
  }

  @Override
  public String getName() {
    return NAME;
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Correct the op token to one of the PUT Op constants in PutOpParam.java:25-63 (all-uppercase, exact).
  2. Verify the verb: APPEND/CONCAT/TRUNCATE/UNSET* are POST, DELETE/DELETESNAPSHOT are DELETE.
  3. If the op is a newer one (SETQUOTA, SATISFYSTORAGEPOLICY, SETECPOLICY), confirm the NameNode version supports it; otherwise use the RPC/Java client.
  4. Prefer the webhdfs:// FileSystem client which maps FileSystem API calls to valid op/verb pairs.

Example fix

# before
curl -i -X PUT "http://nn:9870/webhdfs/v1/dir?op=MKDIR"
# after
curl -i -X PUT "http://nn:9870/webhdfs/v1/dir?op=MKDIRS"
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> PUT_OPS = Set.of("CREATE","MKDIRS","CREATESYMLINK","RENAME","SETREPLICATION","SETOWNER","SETPERMISSION","SETTIMES","RENEWDELEGATIONTOKEN","CANCELDELEGATIONTOKEN","MODIFYACLENTRIES","REMOVEACLENTRIES","REMOVEDEFAULTACL","REMOVEACL","SATISFYSTORAGEPOLICY","SETACL","SETXATTR","REMOVEXATTR","ENABLEECPOLICY","DISABLEECPOLICY","SETECPOLICY","ALLOWSNAPSHOT","DISALLOWSNAPSHOT","CREATESNAPSHOT","RENAMESNAPSHOT","SETSTORAGEPOLICY","SETQUOTA","SETQUOTABYSTORAGETYPE");
static String checkedPutOp(String op) {
  String v = op.toUpperCase(Locale.ROOT);
  if (!PUT_OPS.contains(v)) throw new IllegalArgumentException("op must be one of " + PUT_OPS + ": " + op);
  return v;
}

Type guard

static boolean isValidPutOp(String op, Set<String> clusterSupported) {
  return op != null && clusterSupported.contains(op.toUpperCase(Locale.ROOT));
}

Prevention

When it happens

Trigger: PUT ?op=APPEND or ?op=CONCAT (POST ops); PUT ?op=DELETE (DELETE op); PUT ?op=SETPERM (typo for SETPERMISSION); PUT ?op=SETQUOTA against a pre-3.x NameNode (op added later); PUT ?op=Mkdirs is fine case-wise but 'MKDIR' (missing S) fails.

Common situations: Copy-pasting op values across verb families from mixed documentation; older clusters lacking newer ops (SETQUOTA, SETQUOTABYSTORAGETYPE, SATISFYSTORAGEPOLICY, EC ops); templated clients that concat the operation name from user input.

Related errors


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