{"id":"3e00469f5a5d8bba","repo":"apache/kafka","slug":"the-configured-group-id-should-not-be-an-empty-str","errorCode":null,"errorMessage":"The configured group.id should not be an empty string or whitespace.","messagePattern":"The configured group\\.id should not be an empty string or whitespace\\.","errorType":"exception","errorClass":"org.apache.kafka.common.errors.InvalidGroupIdException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java","lineNumber":841,"sourceCode":"\n    private Optional<ConsumerGroupMetadata> initializeGroupMetadata(final ConsumerConfig config,\n                                                                    final GroupRebalanceConfig groupRebalanceConfig) {\n        final Optional<ConsumerGroupMetadata> groupMetadata = initializeGroupMetadata(\n            groupRebalanceConfig.groupId,\n            groupRebalanceConfig.groupInstanceId\n        );\n        if (groupMetadata.isEmpty()) {\n            config.ignore(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG);\n            config.ignore(THROW_ON_FETCH_STABLE_OFFSET_UNSUPPORTED);\n        }\n        return groupMetadata;\n    }\n\n    private Optional<ConsumerGroupMetadata> initializeGroupMetadata(final String groupId,\n                                                                    final Optional<String> groupInstanceId) {\n        if (groupId != null) {\n            if (groupId.isEmpty()) {\n                throw new InvalidGroupIdException(\"The configured \" + ConsumerConfig.GROUP_ID_CONFIG\n                    + \" should not be an empty string or whitespace.\");\n            } else {\n                return Optional.of(initializeConsumerGroupMetadata(groupId, groupInstanceId));\n            }\n        }\n        return Optional.empty();\n    }\n\n    @SuppressWarnings(\"removal\")\n    private ConsumerGroupMetadata initializeConsumerGroupMetadata(final String groupId,\n                                                                  final Optional<String> groupInstanceId) {\n        return new ConsumerGroupMetadata(\n            groupId,\n            JoinGroupRequest.UNKNOWN_GENERATION_ID,\n            JoinGroupRequest.UNKNOWN_MEMBER_ID,\n            groupInstanceId\n        );\n    }","sourceCodeStart":823,"sourceCodeEnd":859,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java#L823-L859","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set group.id to a non-empty, trimmed string (e.g. \"order-service-consumer\").","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.","Sanitize the source: ensure env vars/config files yield a non-empty value and trim whitespace before passing to the consumer config."],"exampleFix":"// before\nString groupId = System.getenv().getOrDefault(\"KAFKA_GROUP_ID\", \"\");\nprops.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);\n\n// after\nString groupId = System.getenv(\"KAFKA_GROUP_ID\");\nif (groupId == null || groupId.isBlank()) {\n    throw new IllegalStateException(\"KAFKA_GROUP_ID must be set\");\n}\nprops.put(ConsumerConfig.GROUP_ID_CONFIG, groupId.trim());","handlingStrategy":"validation","validationCode":"// group.id must be present AND non-blank whenever you intend to use\n// group-management, commit, or auto-offset features.\nstatic String requireValidGroupId(Properties props) {\n    String gid = props.getProperty(ConsumerConfig.GROUP_ID_CONFIG);\n    if (gid == null)\n        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + \" is required for group-managed consumption\");\n    if (gid.trim().isEmpty())\n        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + \" must not be empty or whitespace\");\n    // Defensive: reject control chars and the max length upstream brokers enforce\n    if (gid.chars().anyMatch(c -> Character.isISOControl(c)))\n        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + \" contains control characters\");\n    if (gid.length() > 249)\n        throw new IllegalArgumentException(ConsumerConfig.GROUP_ID_CONFIG + \" exceeds 249 characters\");\n    return gid;\n}\n\n// Call BEFORE: new KafkaConsumer<>(props, ...)\n// If you genuinely want a stand-alone (assign-only) consumer, set group.id to null\n// (omit the property) — but then you cannot commit offsets or rebalance.","typeGuard":null,"tryCatchPattern":"// InvalidGroupIdException extends ApiException -> typically surfaces wrapped in\n// KafkaException at construction. Catch it to give a precise operator message.\ntry {\n    consumer = new KafkaConsumer<>(props, keyDeser, valDeser);\n} catch (KafkaException e) {\n    if (e.getCause() instanceof org.apache.kafka.common.errors.InvalidGroupIdException) {\n        throw new IllegalStateException(\n            \"Configuration error: \" + ConsumerConfig.GROUP_ID_CONFIG +\n            \" is missing or blank. Set it to a non-empty identifier.\", e);\n    }\n    throw e;\n}","preventionTips":["Treat group.id as required input for any consumer that commits offsets or uses subscribe(); validate it at config-load time, not at construction.","Source group.id from a single named environment variable / config key; never derive it from free-form user input without trimming and checking emptiness.","If running a stand-alone (manual assign) consumer that never commits, deliberately omit group.id and document why, so a future maintainer doesn't re-add an empty string.","Add a startup self-check that fails the process fast rather than letting the consumer crash-loop in a container."],"tags":["consumer","configuration","group-id","validation"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}