apache/seatunnel · error · IllegalArgumentException

client_id is required when clean_session=false for MQTT sour

Error message

client_id is required when clean_session=false for MQTT source

What it means

MqttSourceConfig's constructor throws IllegalArgumentException when clean_session=false but no client_id is configured. With a persistent session, the broker stores subscriptions against the client_id, so an auto-generated random client_id would create a new orphaned session on every reconnect. A client_id is mandatory to make clean_session=false meaningful.

Source

Thrown at seatunnel-connectors-v2/connector-mqtt/src/main/java/org/apache/seatunnel/connectors/seatunnel/mqtt/source/MqttSourceConfig.java:58

    private final int maxQueueSize;

    public MqttSourceConfig(ReadonlyConfig config) {
        this.url = config.get(MqttSourceOptions.URL);
        this.topic = config.get(MqttSourceOptions.TOPIC);
        this.username = config.get(MqttSourceOptions.USERNAME);
        this.password = config.get(MqttSourceOptions.PASSWORD);
        this.qos = config.get(MqttSourceOptions.QOS);
        this.format = config.get(MqttSourceOptions.FORMAT);
        this.fieldDelimiter = config.get(MqttSourceOptions.FIELD_DELIMITER);
        this.cleanSession = config.get(MqttSourceOptions.CLEAN_SESSION);
        this.connectionTimeout = config.get(MqttSourceOptions.CONNECTION_TIMEOUT);
        this.keepAliveInterval = config.get(MqttSourceOptions.KEEP_ALIVE_INTERVAL);
        this.reconnectTimeout = config.get(MqttSourceOptions.RECONNECT_TIMEOUT);
        this.maxQueueSize = config.get(MqttSourceOptions.MAX_QUEUE_SIZE);

        String configuredClientId = config.get(MqttSourceOptions.CLIENT_ID);
        if (!cleanSession && isBlank(configuredClientId)) {
            throw new IllegalArgumentException(
                    "client_id is required when clean_session=false for MQTT source");
        }
        this.clientId =
                isBlank(configuredClientId)
                        ? CLIENT_ID_PREFIX + UUID.randomUUID().toString()
                        : configuredClientId;

        validate();
    }

    private void validate() {
        if (qos < 0 || qos > 1) {
            throw new IllegalArgumentException("MQTT source qos must be 0 or 1, got: " + qos);
        }
        if (!"json".equalsIgnoreCase(format) && !"text".equalsIgnoreCase(format)) {
            throw new IllegalArgumentException("Unsupported MQTT source format: " + format);
        }
        if (reconnectTimeout <= 0) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add an explicit, stable client_id to the MQTT source config
  2. Alternatively set clean_session = true if persistence is not required
  3. Ensure the client_id is unique per source instance sharing the same broker

Example fix

// before
source {
  Mqtt {
    clean_session = false
  }
}
// after
source {
  Mqtt {
    clean_session = false
    client_id = "seatunnel-source-1"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

if (!cleanSession && (clientId == null || clientId.trim().isEmpty())) {
  throw new IllegalArgumentException("client_id is required when clean_session=false");
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Configuring the MQTT source with clean_session = false while omitting client_id (or providing only whitespace, which isBlank also rejects); constructor fails during source initialization.

Common situations: Users enabling persistent sessions for at-least-once semantics but forgetting client_id; copying example configs that use auto-generated client ids; whitespace-only client_id values that look set but are blank.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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