apache/flink · error · IllegalArgumentException

The output cardinality cannot be smaller than zero.

Error message

The output cardinality cannot be smaller than zero.

What it means

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.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/CompilerHints.java:68

    public long getOutputSize() {
        return outputSize;
    }

    public void setOutputSize(long outputSize) {
        if (outputSize < 0) {
            throw new IllegalArgumentException("The output size cannot be smaller than zero.");
        }

        this.outputSize = outputSize;
    }

    public long getOutputCardinality() {
        return this.outputCardinality;
    }

    public void setOutputCardinality(long outputCardinality) {
        if (outputCardinality < 0) {
            throw new IllegalArgumentException(
                    "The output cardinality cannot be smaller than zero.");
        }

        this.outputCardinality = outputCardinality;
    }

    public float getAvgOutputRecordSize() {
        return this.avgOutputRecordSize;
    }

    public void setAvgOutputRecordSize(float avgOutputRecordSize) {
        if (avgOutputRecordSize <= 0) {
            throw new IllegalArgumentException("The size of produced records must be positive.");
        }

        this.avgOutputRecordSize = avgOutputRecordSize;
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure the cardinality value is >= 0 before calling setOutputCardinality().
  2. Guard against arithmetic underflow: use Math.max(0, computed) before setting.
  3. If the value is genuinely unknown, omit the call (the default -1 signals 'unset' to the optimizer).

Example fix

// before
hints.setOutputCardinality(totalRecords - filteredRecords);  // may underflow
// after
long safeCardinality = Math.max(0, totalRecords - filteredRecords);
hints.setOutputCardinality(safeCardinality);
Defensive patterns

Strategy: validation

Validate before calling

// Guard against negative cardinality before setting
if (outputCardinality < 0) {
    throw new IllegalArgumentException("outputCardinality must be >= 0, got: " + outputCardinality);
}
hints.setOutputCardinality(outputCardinality);
// Or omit the call if unknown (default -1 means 'unset')

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/fbcc705e3f6ac721. Report an issue: GitHub.