{"id":"b7094d610bf8a98d","repo":"apache/kafka","slug":"value-s-must-be-one-of-s","errorCode":null,"errorMessage":"Value %s must be one of %s","messagePattern":"Value (.+?) must be one of (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/ElectionType.java","lineNumber":44,"sourceCode":" * Options for {@link org.apache.kafka.clients.admin.Admin#electLeaders(ElectionType, Set, org.apache.kafka.clients.admin.ElectLeadersOptions)}.\n */\n@InterfaceAudience.Public\npublic enum ElectionType {\n    PREFERRED((byte) 0), UNCLEAN((byte) 1);\n\n    public final byte value;\n\n    ElectionType(byte value) {\n        this.value = value;\n    }\n\n    public static ElectionType valueOf(byte value) {\n        if (value == PREFERRED.value) {\n            return PREFERRED;\n        } else if (value == UNCLEAN.value) {\n            return UNCLEAN;\n        } else {\n            throw new IllegalArgumentException(\n                    String.format(\"Value %s must be one of %s\", value, Arrays.asList(ElectionType.values())));\n        }\n    }\n}\n","sourceCodeStart":26,"sourceCodeEnd":49,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/ElectionType.java#L26-L49","documentation":"Thrown by ElectionType.valueOf(byte) when deserializing an election type code from the wire (or any caller) that is neither 0 (PREFERRED) nor 1 (UNCLEAN). It is most often hit when the client receives an ElectLeaders response/request or admin invocation carrying an unexpected byte, or when application/protocol code passes an out-of-range election type. The message formats the offending value and the list of valid enum constants to aid diagnosis.","triggerScenarios":"Admin.electLeaders being called with a manually-cast byte that is out of range; deserialization of a broker response that contains an election_type field with a value outside {0,1}; a broker-client version mismatch where a newer broker sends a value the older client enum does not know; reflection/manual byte construction passed into ElectionType.valueOf.","commonSituations":"Rolling upgrade where broker uses a new ElectionType value not yet present in the older client jar; tests/mocks that fabricate raw bytes; custom admin tooling that hardcodes an integer instead of using ElectionType.PREFERRED/UNCLEAN; cross-version cluster where a tool compiled against one Kafka version talks to another.","solutions":["Always use ElectionType.PREFERRED or ElectionType.UNCLEAN constants rather than raw bytes when calling Admin.electLeaders.","Upgrade the client jar to match (or exceed) the broker version so all wire-defined election types are recognized.","If deserializing from the wire, validate the byte against the known set before calling valueOf and surface a clearer protocol error.","For tests/mocks, use the enum constants or ElectionType.values() instead of hand-crafted integers."],"exampleFix":"// before\nElectionType t = ElectionType.valueOf((byte) 2);  // throws 297\nadmin.electLeaders(t, partitions);\n\n// after\nElectionType t = ElectionType.PREFERRED;  // 0\nadmin.electLeaders(t, partitions);","handlingStrategy":"validation","validationCode":"// Validate a byte against the known election types before calling ElectionType.valueOf:\nbyte candidate = value;\nif (candidate != ElectionType.PREFERRED.value && candidate != ElectionType.UNCLEAN.value) {\n    throw new IllegalArgumentException(\"Invalid election type byte: \" + candidate\n        + \"; must be 0 (PREFERRED) or 1 (UNCLEAN)\");\n}\nElectionType type = ElectionType.valueOf(candidate);","typeGuard":"import java.util.Arrays;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport org.apache.kafka.common.ElectionType;\n\npublic static boolean isValidElectionType(byte id) {\n    return id == ElectionType.PREFERRED.value || id == ElectionType.UNCLEAN.value;\n}\n\npublic static Set<Byte> allowedElectionTypes() {\n    return Arrays.stream(ElectionType.values())\n        .map(t -> t.value).collect(Collectors.toSet());\n}","tryCatchPattern":"try {\n    ElectionType type = ElectionType.valueOf(id);\n} catch (IllegalArgumentException e) {\n    // Map to a user-facing 400 if it came from a request, or default to PREFERRED.\n    throw new IllegalArgumentException(\"Unsupported election type \" + id\n        + \"; supported values are 0 (PREFERRED), 1 (UNCLEAN)\", e);\n}","preventionTips":["Never pass user-supplied bytes directly to ElectionType.valueOf — guard at the API boundary.","Whitelist known values from configuration (preferred/unclean names) and convert from the enum constant instead of from raw bytes.","If you must accept a byte, validate with isValidElectionType(byte) before the call."],"tags":["admin","protocol","enum","deserialization"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}