apache/kafka · error · SchemaException
Unsupported subscription version: {}
Error message
Unsupported subscription version: {} What it means
Thrown by ConsumerProtocol.checkSubscriptionVersion() when the supplied subscription version is below ConsumerProtocolSubscription.LOWEST_SUPPORTED_VERSION. Kafka only guarantees backward compatibility down to LOWEST_SUPPORTED_VERSION; anything older is rejected outright. Versions above HIGHEST_SUPPORTED_VERSION are silently capped (forward-compatibility), so this exception only fires for too-old versions.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerProtocol.java:217
final ByteBuffer buffer,
short version
) {
version = checkAssignmentVersion(version);
try {
return new ConsumerProtocolAssignment(new ByteBufferAccessor(buffer), version);
} catch (RuntimeException e) {
throw new SchemaException("Malformed consumer protocol assignment", e);
}
}
public static ConsumerProtocolAssignment deserializeConsumerProtocolAssignment(final ByteBuffer buffer) {
return deserializeConsumerProtocolAssignment(buffer, deserializeVersion(buffer));
}
private static short checkSubscriptionVersion(final short version) {
if (version < ConsumerProtocolSubscription.LOWEST_SUPPORTED_VERSION)
throw new SchemaException("Unsupported subscription version: " + version);
else if (version > ConsumerProtocolSubscription.HIGHEST_SUPPORTED_VERSION)
return ConsumerProtocolSubscription.HIGHEST_SUPPORTED_VERSION;
else
return version;
}
private static short checkAssignmentVersion(final short version) {
if (version < ConsumerProtocolAssignment.LOWEST_SUPPORTED_VERSION)
throw new SchemaException("Unsupported assignment version: " + version);
else if (version > ConsumerProtocolAssignment.HIGHEST_SUPPORTED_VERSION)
return ConsumerProtocolAssignment.HIGHEST_SUPPORTED_VERSION;
else
return version;
}
}
View on GitHub (pinned to c31c9215e1)
Solutions
- Log the offending version value to confirm whether it is a real legacy version or a parsing corruption (0 typically signals corruption).
- If legitimately reading legacy data, downgrade the reader to a Kafka client version whose LOWEST_SUPPORTED_VERSION covers it.
- If the version came from deserializeVersion, validate buffer length/contents (see Buffer underflow error) before trusting the header.
- Regenerate the subscription payload via ConsumerProtocol.serializeSubscription (no explicit version) so it uses HIGHEST_SUPPORTED_VERSION.
Example fix
// before ConsumerProtocol.serializeSubscription(sub, (short) 0); // after ConsumerProtocol.serializeSubscription(sub); // uses HIGHEST_SUPPORTED_VERSION
Defensive patterns
Strategy: validation
Validate before calling
// checkSubscriptionVersion rejects versions below LOWEST_SUPPORTED_VERSION.
// Validate (and optionally clamp) the version before any (de)serialize call.
import org.apache.kafka.common.message.ConsumerProtocolSubscription;
static short ensureSupportedSubscriptionVersion(short version) {
if (version < ConsumerProtocolSubscription.LOWEST_SUPPORTED_VERSION)
throw new IllegalArgumentException(
"subscription version " + version + " below lowest supported "
+ ConsumerProtocolSubscription.LOWEST_SUPPORTED_VERSION);
return (short) Math.min(version, ConsumerProtocolSubscription.HIGHEST_SUPPORTED_VERSION);
} Type guard
// Narrow a candidate version to the supported subscription-protocol range.
static boolean isSupportedSubscriptionVersion(short v) {
return v >= ConsumerProtocolSubscription.LOWEST_SUPPORTED_VERSION
&& v <= ConsumerProtocolSubscription.HIGHEST_SUPPORTED_VERSION;
} Try / catch
try {
ConsumerProtocol.serializeSubscription(subscription, version);
} catch (org.apache.kafka.common.protocol.types.SchemaException e) {
// Reached only if version < LOWEST_SUPPORTED_VERSION — indicates stale client
// reading bytes written by an even older client, or a hand-crafted version field.
log.error("Unsupported consumer protocol subscription version", e);
throw e;
} Prevention
- Do not pin the consumer protocol version by hand; let ConsumerProtocol.serializeSubscription() use HIGHEST_SUPPORTED_VERSION by default.
- Upgrade all members of a consumer group together so none tries to decode bytes from a removed legacy version.
- If you must interoperate with a legacy client, negotiate the lowest version both sides support before serializing.
When it happens
Trigger: Calling ConsumerProtocol.serializeSubscription or deserializeSubscription/deserializeConsumerProtocolSubscription with an explicit version argument less than LOWEST_SUPPORTED_VERSION (typically negative numbers or 0). Usually arises when a version short is read from a malformed or zeroed header byte, or when a custom caller passes a hardcoded legacy version.
Common situations: A corrupted version prefix (all-zero bytes deserialize as version 0); custom test fixtures passing version 0 or -1; an old snapshot replayed against a client whose LOWEST_SUPPORTED_VERSION has moved up after a Kafka release.
Related errors
- Malformed consumer protocol subscription
- Unsupported assignment version: {}
- Buffer underflow while parsing consumer protocol's header
- Malformed consumer protocol assignment
- Buffer underflow while parsing response for request with hea
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/598defaa5e8212b4.json.
Report an issue: GitHub.