apache/kafka · error · org.apache.kafka.common.errors.InvalidGroupIdException

The configured group.id should not be an empty string or whi

Error message

The configured group.id should not be an empty string or whitespace.

What it means

Thrown by the ClassicKafkaConsumer constructor as an InvalidGroupIdException when group.id is non-null but empty or whitespace. The config parser turns a missing group.id into null (treated as the default/no-group standalone consumer), but an explicit empty string cannot be a valid group identifier, so construction fails fast. This keeps callers from accidentally joining a group with an unusable id, which would otherwise cause coordinator failures later.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java:162

    private final List<ConsumerPartitionAssignor> assignors;
    // Init value is needed to avoid NPE in case of exception raised in the constructor
    private Optional<ClientTelemetryReporter> clientTelemetryReporter = Optional.empty();

    // currentThread holds the threadId of the current thread accessing this Consumer
    // and is used to prevent multi-threaded access
    private final AtomicLong currentThread = new AtomicLong(NO_CURRENT_THREAD);
    // refcount is used to allow reentrant access by the thread who has acquired currentThread
    private final AtomicInteger refcount = new AtomicInteger(0);

    // to keep from repeatedly scanning subscriptions in poll(), cache the result during metadata updates
    private boolean cachedSubscriptionHasAllFetchPositions;

    ClassicKafkaConsumer(ConsumerConfig config, Deserializer<K> keyDeserializer, Deserializer<V> valueDeserializer) {
        try {
            GroupRebalanceConfig groupRebalanceConfig = new GroupRebalanceConfig(config,
                    GroupRebalanceConfig.ProtocolType.CONSUMER);
            if (groupRebalanceConfig.groupId != null && groupRebalanceConfig.groupId.isEmpty()) {
                throw new InvalidGroupIdException("The configured " + ConsumerConfig.GROUP_ID_CONFIG
                        + " should not be an empty string or whitespace.");
            }

            this.groupId = Optional.ofNullable(groupRebalanceConfig.groupId);
            this.clientId = config.getString(CommonClientConfigs.CLIENT_ID_CONFIG);
            LogContext logContext = createLogContext(config, groupRebalanceConfig);
            this.log = logContext.logger(getClass());
            boolean enableAutoCommit = config.getBoolean(ENABLE_AUTO_COMMIT_CONFIG);

            log.debug("Initializing the Kafka consumer");
            this.requestTimeoutMs = config.getInt(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG);
            this.defaultApiTimeoutMs = config.getInt(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG);
            this.time = Time.SYSTEM;
            List<MetricsReporter> reporters = CommonClientConfigs.metricsReporters(clientId, config);
            this.clientTelemetryReporter = CommonClientConfigs.telemetryReporter(clientId, config);
            this.clientTelemetryReporter.ifPresent(reporters::add);
            this.metrics = createMetrics(config, time, reporters);
            this.retryBackoffMs = config.getLong(ConsumerConfig.RETRY_BACKOFF_MS_CONFIG);

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Set group.id to a concrete non-empty value, e.g. group.id=order-service-consumer.
  2. If you intend to run without consumer-group coordination, omit group.id entirely (or set it explicitly to null) rather than blank.
  3. Audit property templating: use a default that is non-empty, e.g. group.id=${KAFKA_GROUP:order-service}, and fail startup if the resolved value is blank.
  4. For Spring Boot, set spring.kafka.consumer.group-id to a real value or remove the property so the framework does not pass an empty string.

Example fix

# before
group.id=

# after
group.id=order-service-consumer
Defensive patterns

Strategy: validation

Validate before calling

// Validate group.id before constructing the consumer.
String groupId = props.getProperty(ConsumerConfig.GROUP_ID_CONFIG);
if (groupId == null || groupId.trim().isEmpty()) {
    throw new IllegalArgumentException(
        ConsumerConfig.GROUP_ID_CONFIG + " must be a non-empty, non-whitespace string");
}
new KafkaConsumer<K,V>(props);

Type guard

// Static helper that returns a sanitized group.id or fails fast.
static String requireGroupId(Properties p) {
    String g = p.getProperty(ConsumerConfig.GROUP_ID_CONFIG);
    if (g == null || g.trim().isEmpty())
        throw new IllegalArgumentException("group.id is blank");
    return g;
}

Try / catch

try {
    consumer = new KafkaConsumer<K,V>(props);
} catch (org.apache.kafka.common.errors.InvalidGroupIdException e) {
    log.error("group.id misconfigured; falling back to default", e);
    props.setProperty(ConsumerConfig.GROUP_ID_CONFIG, defaultGroupId);
    consumer = new KafkaConsumer<K,V>(props);
}

Prevention

When it happens

Trigger: Setting group.id="" or group.id=" " in consumer properties; a placeholder like group.id=${KAFKA_GROUP:} where the env var default resolves to empty; Spring Boot's spring.kafka.consumer.group-id bound to an empty property; reading group.id from a YAML key that is present but blank.

Common situations: Environment-variable templating that produces an empty string when the variable is unset; container/secret-injection that writes group.id= into a properties file; test configs that blank out group.id to 'disable' grouping (use null instead); copy-paste configs between services without updating the group id.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/5238966def7a3de4.json. Report an issue: GitHub.