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
- Set group.id to a concrete non-empty value, e.g. group.id=order-service-consumer.
- If you intend to run without consumer-group coordination, omit group.id entirely (or set it explicitly to null) rather than blank.
- 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.
- 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
- Load group.id from a single validated config source (env var / KDL / properties) with a startup assertion.
- Trim and check non-empty in your config loader, not deep inside Kafka client construction.
- For standalone consumers with no group, explicitly set group.override.strategy or use assign() instead of subscribe().
- Add an integration test that the app fails fast when group.id is missing.
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
- Topic collection to subscribe to cannot contain null or empt
- The configured group.id should not be an empty string or whi
- Topic collection to subscribe to cannot contain null or empt
- Failed to construct kafka consumer
- RebalanceListener cannot be null
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/5238966def7a3de4.json.
Report an issue: GitHub.