{"record":{"id":"c12e77d178f21f5c","repo":"apache/kafka","slug":"cannot-specify-a-negative-version-level","errorCode":null,"errorMessage":"Cannot specify a negative version level.","messagePattern":"Cannot specify a negative version level\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/admin/FeatureUpdate.java","lineNumber":78,"sourceCode":"\n    /**\n     * @param maxVersionLevel   The new maximum version level for the finalized feature.\n     *                          a value of zero is special and indicates that the update is intended to\n     *                          delete the finalized feature, and should be accompanied by setting\n     *                          the upgradeType to safe or unsafe.\n     * @param upgradeType     Indicate what kind of upgrade should be performed in this operation.\n     *                          - UPGRADE: upgrading the feature level\n     *                          - SAFE_DOWNGRADE: only downgrades which do not result in metadata loss are permitted\n     *                          - UNSAFE_DOWNGRADE: any downgrade, including those which may result in metadata loss, are permitted\n     */\n    public FeatureUpdate(final short maxVersionLevel, final UpgradeType upgradeType) {\n        if (maxVersionLevel == 0 && upgradeType.equals(UpgradeType.UPGRADE)) {\n            throw new IllegalArgumentException(String.format(\n                    \"The upgradeType flag should be set to SAFE_DOWNGRADE or UNSAFE_DOWNGRADE when the provided maxVersionLevel:%d is < 1.\",\n                    maxVersionLevel));\n        }\n        if (maxVersionLevel < 0) {\n            throw new IllegalArgumentException(\"Cannot specify a negative version level.\");\n        }\n        this.maxVersionLevel = maxVersionLevel;\n        this.upgradeType = upgradeType;\n    }\n\n    public short maxVersionLevel() {\n        return maxVersionLevel;\n    }\n\n    public UpgradeType upgradeType() {\n        return upgradeType;\n    }\n\n    @Override\n    public boolean equals(Object other) {\n        if (this == other) {\n            return true;\n        }","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/clients/src/main/java/org/apache/kafka/clients/admin/FeatureUpdate.java#L60-L96","documentation":"Thrown by the FeatureUpdate constructor when maxVersionLevel is a negative short. Kafka finalized feature version levels are non-negative; a negative value is either a parsing bug or an underflow and is rejected immediately on the client.","triggerScenarios":"Calling new FeatureUpdate with a negative short, e.g. new FeatureUpdate((short) -1, ...). Building a FeatureUpdate from untrusted/external input that was parsed as a signed value without bounds checking. Arithmetic that wraps a short below zero.","commonSituations":"Tooling that lets a user type a version level of -1 to mean 'unset'; parsing a protobuf/JSON number into a short without validation; porting code where -1 was previously a sentinel.","solutions":["Pass a non-negative maxVersionLevel (0 for delete, >= 1 for a real level).","Validate the parsed value with a range check (>= 0) before constructing the FeatureUpdate.","Treat -1/'unset' from your own config layer as 'do not send a FeatureUpdate' rather than forwarding it."],"exampleFix":"// before\nshort level = Short.parseShort userInput; // -1 possible\nnew FeatureUpdate(level, upgradeType);\n\n// after\nif (level < 0) throw new IllegalArgumentException(\"level must be >= 0: \" + level);\nnew FeatureUpdate(level, upgradeType);","handlingStrategy":"validation","validationCode":"if (level < 0) {\n    throw new IllegalArgumentException(\"level must be >= 0: \" + level);\n}\nnew FeatureUpdate(level, upgradeType);","typeGuard":"static boolean isNonNegativeLevel(short level) {\n    return level >= 0;\n}","tryCatchPattern":"try {\n    new FeatureUpdate(level, upgradeType);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"negative\")) {\n        // reject input upstream\n    }\n}","preventionTips":["Range-check any externally-sourced level (>= 0) before constructing FeatureUpdate.","Map application-level 'unset' to 'skip the request' rather than to -1."],"tags":["kafka-admin","feature-versioning","argument-validation","client-side"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}