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

InvalidGroupIdException thrown by AsyncKafkaConsumer.initializeGroupMetadata when group.id is provided but resolves to an empty string. The consumer treats a present-but-empty group.id as a programming error rather than silently proceeding: an empty group cannot join, commit, or rebalance, so construction is aborted early. A null group.id is allowed (enables assign-only consumers without group coordination); only empty/whitespace strings are rejected.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java:841

    private Optional<ConsumerGroupMetadata> initializeGroupMetadata(final ConsumerConfig config,
                                                                    final GroupRebalanceConfig groupRebalanceConfig) {
        final Optional<ConsumerGroupMetadata> groupMetadata = initializeGroupMetadata(
            groupRebalanceConfig.groupId,
            groupRebalanceConfig.groupInstanceId
        );
        if (groupMetadata.isEmpty()) {
            config.ignore(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG);
            config.ignore(THROW_ON_FETCH_STABLE_OFFSET_UNSUPPORTED);
        }
        return groupMetadata;
    }

    private Optional<ConsumerGroupMetadata> initializeGroupMetadata(final String groupId,
                                                                    final Optional<String> groupInstanceId) {
        if (groupId != null) {
            if (groupId.isEmpty()) {
                throw new InvalidGroupIdException("The configured " + ConsumerConfig.GROUP_ID_CONFIG
                    + " should not be an empty string or whitespace.");
            } else {
                return Optional.of(initializeConsumerGroupMetadata(groupId, groupInstanceId));
            }
        }
        return Optional.empty();
    }

    @SuppressWarnings("removal")
    private ConsumerGroupMetadata initializeConsumerGroupMetadata(final String groupId,
                                                                  final Optional<String> groupInstanceId) {
        return new ConsumerGroupMetadata(
            groupId,
            JoinGroupRequest.UNKNOWN_GENERATION_ID,
            JoinGroupRequest.UNKNOWN_MEMBER_ID,
            groupInstanceId
        );
    }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Set group.id to a non-empty, trimmed string (e.g. "order-service-consumer").
  2. If your consumer uses manual assignment only and does not need a group, set group.id to null or omit it entirely rather than passing an empty string.
  3. Sanitize the source: ensure env vars/config files yield a non-empty value and trim whitespace before passing to the consumer config.

Example fix

// before
String groupId = System.getenv().getOrDefault("KAFKA_GROUP_ID", "");
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);

// after
String groupId = System.getenv("KAFKA_GROUP_ID");
if (groupId == null || groupId.isBlank()) {
    throw new IllegalStateException("KAFKA_GROUP_ID must be set");
}
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId.trim());
Defensive patterns

Strategy: validation

Validate before calling

// group.id must be present AND non-blank whenever you intend to use
// group-management, commit, or auto-offset features.
static String requireValidGroupId(Properties props) {
    String gid = props.getProperty(ConsumerConfig.GROUP_ID_CONFIG);
    if (gid == null)
        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + " is required for group-managed consumption");
    if (gid.trim().isEmpty())
        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + " must not be empty or whitespace");
    // Defensive: reject control chars and the max length upstream brokers enforce
    if (gid.chars().anyMatch(c -> Character.isISOControl(c)))
        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + " contains control characters");
    if (gid.length() > 249)
        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + " exceeds 249 characters");
    return gid;
}

// Call BEFORE: new KafkaConsumer<>(props, ...)
// If you genuinely want a stand-alone (assign-only) consumer, set group.id to null
// (omit the property) — but then you cannot commit offsets or rebalance.

Try / catch

// InvalidGroupIdException extends ApiException -> typically surfaces wrapped in
// KafkaException at construction. Catch it to give a precise operator message.
try {
    consumer = new KafkaConsumer<>(props, keyDeser, valDeser);
} catch (KafkaException e) {
    if (e.getCause() instanceof org.apache.kafka.common.errors.InvalidGroupIdException) {
        throw new IllegalStateException(
            "Configuration error: " + ConsumerConfig.GROUP_ID_CONFIG +
            " is missing or blank. Set it to a non-empty identifier.", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting group.id="" or group.id=" " (whitespace only) in ConsumerConfig, then constructing a KafkaConsumer. Common when group.id is sourced from an env var or config file that resolves to an empty string at runtime, or when code does props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId) where groupId is blank.

Common situations: Env var KAFKA_GROUP_ID unset defaults to empty string; templated config (Helm, k8s ConfigMap) missing a value; integration test that forgets to set group.id for a consumer that later calls commit/commit; migration from a static group.id to a configurable one where the new value is blank in some environment.

Related errors


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