apache/seatunnel · error · IllegalArgumentException

batch_size must be >= 1, got:

Error message

batch_size must be >= 1, got: 

What it means

The MQTT sink writer validates the batch_size option in its constructor and rejects values below 1 with an IllegalArgumentException. batch_size controls how many messages are buffered before flushing; zero or negative values would break the batching loop.

Source

Thrown at seatunnel-connectors-v2/connector-mqtt/src/main/java/org/apache/seatunnel/connectors/seatunnel/mqtt/sink/MqttSinkWriter.java:75

    private final int qos;
    private final int retryTimeoutMs;
    private final int batchSize;
    private final SerializationSchema serializationSchema;
    private final List<MqttMessage> messageBuffer;
    private MqttClient mqttClient;

    public MqttSinkWriter(
            SinkWriter.Context context, SeaTunnelRowType rowType, ReadonlyConfig pluginConfig) {
        this.topic = pluginConfig.get(MqttSinkOptions.TOPIC);
        this.qos = pluginConfig.get(MqttSinkOptions.QOS);
        if (this.qos < 0 || this.qos > 1) {
            throw new IllegalArgumentException(
                    "MQTT QoS must be 0 (at-most-once) or 1 (at-least-once), got: " + this.qos);
        }
        this.retryTimeoutMs = pluginConfig.get(MqttSinkOptions.RETRY_TIMEOUT);
        this.batchSize = pluginConfig.get(MqttSinkOptions.BATCH_SIZE);
        if (this.batchSize < 1) {
            throw new IllegalArgumentException("batch_size must be >= 1, got: " + this.batchSize);
        }
        this.messageBuffer = new ArrayList<>(this.batchSize);
        this.serializationSchema = createSerializationSchema(rowType, pluginConfig);

        // Each subtask appends its index and a random UUID to guarantee a globally unique client
        // ID,
        // preventing mutual disconnections and connection hijacking when running parallel jobs.
        String clientId =
                CLIENT_ID_PREFIX
                        + context.getIndexOfSubtask()
                        + "-"
                        + java.util.UUID.randomUUID().toString();

        try {
            // MemoryPersistence avoids file-system I/O; ideal for containerized deployments.
            this.mqttClient =
                    new MqttClient(
                            pluginConfig.get(MqttSinkOptions.URL),

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set batch_size >= 1 (e.g. 10–100 depending on throughput).
  2. To send messages immediately, use batch_size = 1 rather than 0.
  3. Remove the option to fall back to the default batch size.

Example fix

// before
batch_size = 0
// after
batch_size = 1
Defensive patterns

Strategy: validation

Validate before calling

int batchSize = config.getInt("batch_size", 1000);
if (batchSize < 1) {
    throw new IllegalArgumentException("batch_size must be >= 1, got: " + batchSize);
}

Try / catch

try {
    new MqttSinkWriter(context, rowType, pluginConfig);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("batch_size must be >= 1")) {
        // coerce to default batch size or abort job config load
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting `batch_size = 0` or a negative number in the MQTT sink configuration; the constructor reads MqttSinkOptions.BATCH_SIZE and fails the `batchSize < 1` check.

Common situations: Users trying to disable batching by setting batch_size = 0; copy-paste config errors; template placeholders left unfilled.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/4d7f3cb8c0d3c9e8. Report an issue: GitHub.