{"record":{"id":"fbcc705e3f6ac721","repo":"apache/flink","slug":"the-output-cardinality-cannot-be-smaller-than-zero","errorCode":null,"errorMessage":"The output cardinality cannot be smaller than zero.","messagePattern":"The output cardinality cannot be smaller than zero\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/CompilerHints.java","lineNumber":68,"sourceCode":"    public long getOutputSize() {\n        return outputSize;\n    }\n\n    public void setOutputSize(long outputSize) {\n        if (outputSize < 0) {\n            throw new IllegalArgumentException(\"The output size cannot be smaller than zero.\");\n        }\n\n        this.outputSize = outputSize;\n    }\n\n    public long getOutputCardinality() {\n        return this.outputCardinality;\n    }\n\n    public void setOutputCardinality(long outputCardinality) {\n        if (outputCardinality < 0) {\n            throw new IllegalArgumentException(\n                    \"The output cardinality cannot be smaller than zero.\");\n        }\n\n        this.outputCardinality = outputCardinality;\n    }\n\n    public float getAvgOutputRecordSize() {\n        return this.avgOutputRecordSize;\n    }\n\n    public void setAvgOutputRecordSize(float avgOutputRecordSize) {\n        if (avgOutputRecordSize <= 0) {\n            throw new IllegalArgumentException(\"The size of produced records must be positive.\");\n        }\n\n        this.avgOutputRecordSize = avgOutputRecordSize;\n    }\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/CompilerHints.java#L50-L86","documentation":"Thrown by CompilerHints.setOutputCardinality(long) when the provided outputCardinality is negative. The default is -1 (meaning 'unset'); valid cardinality values must be >= 0. The optimizer uses cardinality to estimate the number of records produced, so a negative count is meaningless and rejected with an IllegalArgumentException.","triggerScenarios":"Calling setOutputCardinality() with a negative long value, often due to an arithmetic error or passing an uninitialized/sentinel value. Cardinality hints are set by the optimizer or internal plan builders.","commonSituations":"An @Internal API used in optimizer and plan construction logic. A negative value may come from subtracting more than the current estimate (e.g., cardinalityAfterFilter = cardinality - droppedRecords where droppedRecords > cardinality), or from passing the default -1 sentinel.","solutions":["Ensure the cardinality value is >= 0 before calling setOutputCardinality().","Guard against arithmetic underflow: use Math.max(0, computed) before setting.","If the value is genuinely unknown, omit the call (the default -1 signals 'unset' to the optimizer)."],"exampleFix":"// before\nhints.setOutputCardinality(totalRecords - filteredRecords);  // may underflow\n// after\nlong safeCardinality = Math.max(0, totalRecords - filteredRecords);\nhints.setOutputCardinality(safeCardinality);","handlingStrategy":"validation","validationCode":"// Guard against negative cardinality before setting\nif (outputCardinality < 0) {\n    throw new IllegalArgumentException(\"outputCardinality must be >= 0, got: \" + outputCardinality);\n}\nhints.setOutputCardinality(outputCardinality);\n// Or omit the call if unknown (default -1 means 'unset')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed cardinality to >= 0 with Math.max(0, value).","Do not pass the -1 sentinel into setOutputCardinality().","Guard arithmetic (e.g., subtraction) that may produce negative cardinalities."],"tags":["compiler-hints","validation","argument-check","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}