{"record":{"id":"82e7d19b62685e40","repo":"provectus/kafka-ui","slug":"any-operation-can-be-only-part-of-filter","errorCode":null,"errorMessage":"ANY operation can be only part of filter","messagePattern":"ANY operation can be only part of filter","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/ClusterMapper.java","lineNumber":148,"sourceCode":"        .currentTransactionStartOffset(state.currentTransactionStartOffset().stream().boxed().findAny().orElse(null));\n  }\n\n  static KafkaAclDTO.OperationEnum mapAclOperation(AclOperation operation) {\n    return switch (operation) {\n      case ALL -> KafkaAclDTO.OperationEnum.ALL;\n      case READ -> KafkaAclDTO.OperationEnum.READ;\n      case WRITE -> KafkaAclDTO.OperationEnum.WRITE;\n      case CREATE -> KafkaAclDTO.OperationEnum.CREATE;\n      case DELETE -> KafkaAclDTO.OperationEnum.DELETE;\n      case ALTER -> KafkaAclDTO.OperationEnum.ALTER;\n      case DESCRIBE -> KafkaAclDTO.OperationEnum.DESCRIBE;\n      case CLUSTER_ACTION -> KafkaAclDTO.OperationEnum.CLUSTER_ACTION;\n      case DESCRIBE_CONFIGS -> KafkaAclDTO.OperationEnum.DESCRIBE_CONFIGS;\n      case ALTER_CONFIGS -> KafkaAclDTO.OperationEnum.ALTER_CONFIGS;\n      case IDEMPOTENT_WRITE -> KafkaAclDTO.OperationEnum.IDEMPOTENT_WRITE;\n      case CREATE_TOKENS -> KafkaAclDTO.OperationEnum.CREATE_TOKENS;\n      case DESCRIBE_TOKENS -> KafkaAclDTO.OperationEnum.DESCRIBE_TOKENS;\n      case ANY -> throw new IllegalArgumentException(\"ANY operation can be only part of filter\");\n      case UNKNOWN -> KafkaAclDTO.OperationEnum.UNKNOWN;\n    };\n  }\n\n  static KafkaAclResourceTypeDTO mapAclResourceType(ResourceType resourceType) {\n    return switch (resourceType) {\n      case CLUSTER -> KafkaAclResourceTypeDTO.CLUSTER;\n      case TOPIC -> KafkaAclResourceTypeDTO.TOPIC;\n      case GROUP -> KafkaAclResourceTypeDTO.GROUP;\n      case DELEGATION_TOKEN -> KafkaAclResourceTypeDTO.DELEGATION_TOKEN;\n      case TRANSACTIONAL_ID -> KafkaAclResourceTypeDTO.TRANSACTIONAL_ID;\n      case USER -> KafkaAclResourceTypeDTO.USER;\n      case ANY -> throw new IllegalArgumentException(\"ANY type can be only part of filter\");\n      case UNKNOWN -> KafkaAclResourceTypeDTO.UNKNOWN;\n    };\n  }\n\n  static ResourceType mapAclResourceTypeDto(KafkaAclResourceTypeDTO dto) {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/provectus/kafka-ui/blob/83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7/kafka-ui-api/src/main/java/com/provectus/kafka/ui/mapper/ClusterMapper.java#L130-L166","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Do not use Operation.ANY when creating ACLs — specify a concrete operation (READ, WRITE, ALL, etc.)","Replace ANY with Operation.ALL when the intent was 'all operations'","Audit any internal code path so ACL filter predicates are never fed into the DTO mapper"],"exampleFix":"// before\nnew AclBinding(resource, new AccessControlEntry(principal, host, Operation.ANY, ALLOW));\n// after\nnew AclBinding(resource, new AccessControlEntry(principal, host, Operation.ALL, ALLOW));","handlingStrategy":"type-guard","validationCode":"public static boolean isConcreteOperation(kafka.security.auth.Operation op) {\n  return op != Operation.ANY;\n}\nif (!isConcreteOperation(op)) throw new IllegalArgumentException(\"Use Operation.ALL instead of ANY for ACL creation\");","typeGuard":"const isConcreteOp = (op) => op !== 'ANY';","tryCatchPattern":"try {\n  dto = ClusterMapper.toKafkaAclDto(acl);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"ANY operation\")) {\n    log.warn(\"Filter-only operation ANY leaked into ACL mapping\");\n  }\n}","preventionTips":["Use Operation.ALL, not ANY, when creating broad ACLs","Restrict ANY to ACL filter predicates only, never creation requests","Add an assertion in ACL-building helpers rejecting Operation.ANY"],"tags":["kafka","acl","mapper","unsupported-value"],"backgroundTag":"invalid-enum-value","analyzedSha":"83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7","analyzedAt":"2026-09-08T04:35:39.002Z","contentChangedAt":"2026-09-08T04:35:39.002Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}