apache/flink · error · UnsupportedOperationException

The BulkIteration meta operator cannot have broadcast inputs

Error message

The BulkIteration meta operator cannot have broadcast inputs.

What it means

Thrown by BulkIterationBase.setBroadcastVariable(String, Operator<?>) — this method always throws UnsupportedOperationException. A BulkIteration is a meta-operator that wraps an iteration body; broadcast variables cannot be attached to the iteration itself because the concept does not apply at the meta-operator level. Broadcast variables should be attached to operators within the step function.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/base/BulkIterationBase.java:199

    /**
     * The BulkIteration meta operator cannot have broadcast inputs.
     *
     * @return An empty map.
     */
    public Map<String, Operator<?>> getBroadcastInputs() {
        return Collections.emptyMap();
    }

    /**
     * The BulkIteration meta operator cannot have broadcast inputs. This method always throws an
     * exception.
     *
     * @param name Ignored.
     * @param root Ignored.
     */
    public void setBroadcastVariable(String name, Operator<?> root) {
        throw new UnsupportedOperationException(
                "The BulkIteration meta operator cannot have broadcast inputs.");
    }

    /**
     * The BulkIteration meta operator cannot have broadcast inputs. This method always throws an
     * exception.
     *
     * @param inputs Ignored
     */
    public <X> void setBroadcastVariables(Map<String, Operator<X>> inputs) {
        throw new UnsupportedOperationException(
                "The BulkIteration meta operator cannot have broadcast inputs.");
    }

    // --------------------------------------------------------------------------------------------

    /**
     * Specialized operator to use as a recognizable place-holder for the input to the step function

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Do not call setBroadcastVariable on BulkIterationBase; attach broadcast variables to operators within the step function body instead.
  2. Check operator type before calling setBroadcastVariable; skip BulkIterationBase and DeltaIterationBase.
  3. Use getBroadcastInputs() (which returns an empty map) to check before attempting to set.
  4. Refactor generic operator-processing code to handle iteration meta-operators as special cases.

Example fix

// before
for (Operator<?> op : allOperators) {
    op.setBroadcastVariable("cache", broadcastData); // throws for BulkIterationBase
}

// after
for (Operator<?> op : allOperators) {
    if (!(op instanceof BulkIterationBase) && !(op instanceof DeltaIterationBase)) {
        op.setBroadcastVariable("cache", broadcastData);
    }
    // attach broadcast to operators inside the iteration body separately
}
Defensive patterns

Strategy: type-guard

Validate before calling

void safeSetBroadcastVariable(Operator<?> op, String name, Operator<?> bc) {
    if (op instanceof BulkIterationBase || op instanceof DeltaIterationBase) {
        throw new UnsupportedOperationException(
            "Cannot set broadcast variable on iteration meta-operator: " + op);
    }
    op.setBroadcastVariable(name, bc);
}

Type guard

static boolean canHaveBroadcastInputs(Operator<?> op) {
    return !(op instanceof BulkIterationBase) && !(op instanceof DeltaIterationBase);
}

Try / catch

try {
    op.setBroadcastVariable(name, bcData);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().contains("meta operator")) {
        log.debug("Skipping broadcast set on iteration meta-operator {}", op);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling iteration.setBroadcastVariable("name", someOperator) on a BulkIterationBase instance. Generic code that iterates over operators and calls setBroadcastVariable on each without checking the operator type.

Common situations: Generic visitor or traversal code that treats all operators uniformly and calls setBroadcastVariable on each. Misunderstanding that broadcast variables go on inner operators, not the iteration wrapper. Copy-pasting broadcast setup code across operators including iterations.

Related errors


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