provectus/kafka-ui · error · IllegalArgumentException

ANY operation can be only part of filter

Error message

ANY operation can be only part of filter

What it means

When mapping Kafka ACL entries to the API DTO, ClusterMapper.mapAclOperation switches over kafka.security.auth.Operation values. The pseudo-operation ANY is only valid inside ACL binding filters for matching, never as an actual ACL's operation, so encountering it throws IllegalArgumentException.

Solutions

  1. Do not use Operation.ANY when creating ACLs — specify a concrete operation (READ, WRITE, ALL, etc.)
  2. Replace ANY with Operation.ALL when the intent was 'all operations'
  3. Audit any internal code path so ACL filter predicates are never fed into the DTO mapper

Example fix

// before
new AclBinding(resource, new AccessControlEntry(principal, host, Operation.ANY, ALLOW));
// after
new AclBinding(resource, new AccessControlEntry(principal, host, Operation.ALL, ALLOW));
Defensive patterns

Strategy: type-guard

Validate before calling

public static boolean isConcreteOperation(kafka.security.auth.Operation op) {
  return op != Operation.ANY;
}
if (!isConcreteOperation(op)) throw new IllegalArgumentException("Use Operation.ALL instead of ANY for ACL creation");

Type guard

const isConcreteOp = (op) => op !== 'ANY';

Try / catch

try {
  dto = ClusterMapper.toKafkaAclDto(acl);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("ANY operation")) {
    log.warn("Filter-only operation ANY leaked into ACL mapping");
  }
}

Prevention

When it happens

Trigger: Listing ACLs on a cluster where a stored ACL binding somehow has Operation.ANY, or internal code building ACL filters and passing ANY through toKafkaAclDto/mapAclOperation.

Common situations: Custom tooling that wrote ACLs with ANY via AdminClient; code that reuses a filter spec as a creation request; Kafka version differences surfacing ANY in describe results.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08). Data as JSON: /api/errors/82e7d19b62685e40. Report an issue: GitHub.

Appendix: source

Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/ClusterMapper.java:148

        .currentTransactionStartOffset(state.currentTransactionStartOffset().stream().boxed().findAny().orElse(null));
  }

  static KafkaAclDTO.OperationEnum mapAclOperation(AclOperation operation) {
    return switch (operation) {
      case ALL -> KafkaAclDTO.OperationEnum.ALL;
      case READ -> KafkaAclDTO.OperationEnum.READ;
      case WRITE -> KafkaAclDTO.OperationEnum.WRITE;
      case CREATE -> KafkaAclDTO.OperationEnum.CREATE;
      case DELETE -> KafkaAclDTO.OperationEnum.DELETE;
      case ALTER -> KafkaAclDTO.OperationEnum.ALTER;
      case DESCRIBE -> KafkaAclDTO.OperationEnum.DESCRIBE;
      case CLUSTER_ACTION -> KafkaAclDTO.OperationEnum.CLUSTER_ACTION;
      case DESCRIBE_CONFIGS -> KafkaAclDTO.OperationEnum.DESCRIBE_CONFIGS;
      case ALTER_CONFIGS -> KafkaAclDTO.OperationEnum.ALTER_CONFIGS;
      case IDEMPOTENT_WRITE -> KafkaAclDTO.OperationEnum.IDEMPOTENT_WRITE;
      case CREATE_TOKENS -> KafkaAclDTO.OperationEnum.CREATE_TOKENS;
      case DESCRIBE_TOKENS -> KafkaAclDTO.OperationEnum.DESCRIBE_TOKENS;
      case ANY -> throw new IllegalArgumentException("ANY operation can be only part of filter");
      case UNKNOWN -> KafkaAclDTO.OperationEnum.UNKNOWN;
    };
  }

  static KafkaAclResourceTypeDTO mapAclResourceType(ResourceType resourceType) {
    return switch (resourceType) {
      case CLUSTER -> KafkaAclResourceTypeDTO.CLUSTER;
      case TOPIC -> KafkaAclResourceTypeDTO.TOPIC;
      case GROUP -> KafkaAclResourceTypeDTO.GROUP;
      case DELEGATION_TOKEN -> KafkaAclResourceTypeDTO.DELEGATION_TOKEN;
      case TRANSACTIONAL_ID -> KafkaAclResourceTypeDTO.TRANSACTIONAL_ID;
      case USER -> KafkaAclResourceTypeDTO.USER;
      case ANY -> throw new IllegalArgumentException("ANY type can be only part of filter");
      case UNKNOWN -> KafkaAclResourceTypeDTO.UNKNOWN;
    };
  }

  static ResourceType mapAclResourceTypeDto(KafkaAclResourceTypeDTO dto) {

View on GitHub (pinned to 83b5a60cc0)