# Error Codes (/connectors/kafka/reference/error-codes)



The KubeMQ Kafka connector answers every failure with a **standard Kafka protocol error
code** — the same numeric `ErrorCode` field (top-level, per-partition, or per-resource,
depending on the API) a stock Kafka client already knows how to interpret. There is no
custom error vocabulary: branch your client's retry/reconfigure logic on the numeric code
exactly as you would against real Kafka.

<Callout type="info">
  **Retriable vs. non-retriable.** Codes marked **retriable** reflect a transient condition —
  the broker isn't ready, a race was lost, a coordinator pointer is stale — that a client's
  normal backoff-and-retry resolves. **Non-retriable** means resending the identical request
  will never succeed; something has to change first.
</Callout>

## Version negotiation [#version-negotiation]

| Code | Error                 | What triggers it                                                                                                                                                                                                                             |
| ---- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 35   | `UNSUPPORTED_VERSION` | The request's version falls outside that key's advertised `[min, max]` window (see [Capabilities](/connectors/kafka/reference/capabilities)). Encoded at the key's max version so the client can parse it and renegotiate via `ApiVersions`. |

## Produce and fetch (data plane) [#produce-and-fetch-data-plane]

| Code | Error                          | What triggers it                                                                                                                                                             |
| ---- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1    | `OFFSET_OUT_OF_RANGE`          | `Fetch`/`ListOffsets` requested an offset below the log start or above the high watermark — never used for a valid empty fetch at offset 0. Non-retriable at that offset.    |
| 2    | `CORRUPT_MESSAGE`              | A `Produce` batch failed decode — CRC mismatch, an incomplete/oversized batch, a bad `Magic` byte, or a negative `FirstSequence` from an idempotent producer. Non-retriable. |
| 3    | `UNKNOWN_TOPIC_OR_PARTITION`   | The topic or partition doesn't exist and auto-create didn't apply.                                                                                                           |
| 5    | `LEADER_NOT_AVAILABLE`         | The broker isn't accepting traffic yet — still starting, or a just-promoted leader catching up on Raft. Retriable.                                                           |
| 6    | `NOT_LEADER_OR_FOLLOWER`       | A clustered follower answers this on `Fetch` so the client's metadata refresh re-routes it to the leader. Retriable.                                                         |
| 10   | `MESSAGE_TOO_LARGE`            | A `Produce` partition's `Records` exceed `MaxMessageBytes` (default 1 MiB). Non-retriable — the producer must reconfigure.                                                   |
| 17   | `INVALID_TOPIC_EXCEPTION`      | The topic name fails KubeMQ's channel-name validation — kept distinct from an authorization deny so it never leaks "denied" to an unauthorized caller.                       |
| 21   | `INVALID_REQUIRED_ACKS`        | `Produce`'s `Acks` is set to something other than `0`, `1`, or `-1`. Unreachable by a conformant client. Non-retriable.                                                      |
| 45   | `OUT_OF_ORDER_SEQUENCE_NUMBER` | An idempotent producer's per-`(PID, partition)` sequence check found a gap.                                                                                                  |
| 46   | `DUPLICATE_SEQUENCE_NUMBER`    | The same `(PID, partition)` sequence was already accepted — the connector dedups the retry.                                                                                  |
| 59   | `UNKNOWN_PRODUCER_ID`          | The batch's producer ID has no live sequence-tracking record — expired, or never seen.                                                                                       |
| 74   | `FENCED_LEADER_EPOCH`          | The client's `CurrentLeaderEpoch` is older than the partition's live epoch. Retriable.                                                                                       |
| 75   | `UNKNOWN_LEADER_EPOCH`         | The client's `CurrentLeaderEpoch` is newer than what this node knows. Retriable.                                                                                             |
| 100  | `UNKNOWN_TOPIC_ID`             | A `Metadata` v10+ request named a `TopicID` (KIP-516) that doesn't resolve to any discoverable topic.                                                                        |

## Consumer-group coordinator [#consumer-group-coordinator]

| Code | Error                          | What triggers it                                                                                                                                         |
| ---- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 14   | `COORDINATOR_LOAD_IN_PROGRESS` | The durable offset store hasn't finished replaying at boot. Retriable — a background sweep retries until it succeeds.                                    |
| 15   | `COORDINATOR_NOT_AVAILABLE`    | The broker isn't accepting group-coordinator traffic yet. Retriable.                                                                                     |
| 16   | `NOT_COORDINATOR`              | This node isn't the caught-up Raft leader for the group; surfaces only when the leader-proxy hop fails. Retriable.                                       |
| 22   | `ILLEGAL_GENERATION`           | A Join/Sync/Heartbeat names a generation the coordinator has already moved past.                                                                         |
| 23   | `INCONSISTENT_GROUP_PROTOCOL`  | The group's members can't agree on a common protocol/assignor during a rebalance.                                                                        |
| 24   | `INVALID_GROUP_ID`             | An empty `group.id`.                                                                                                                                     |
| 25   | `UNKNOWN_MEMBER_ID`            | The presented `member.id` is unknown — never joined, already reaped, or an unrecognized static-instance mapping.                                         |
| 26   | `INVALID_SESSION_TIMEOUT`      | `JoinGroupRequest.SessionTimeoutMillis` falls outside the coordinator's accepted bounds.                                                                 |
| 27   | `REBALANCE_IN_PROGRESS`        | The group is (now) rebalancing — the member must rejoin.                                                                                                 |
| 68   | `NON_EMPTY_GROUP`              | `DeleteGroups` targeted a non-Empty group, or `OffsetDelete` targeted an active non-consumer-protocol group.                                             |
| 69   | `GROUP_ID_NOT_FOUND`           | The named group is unknown to the registry and the durable offset store, or its state is Dead.                                                           |
| 79   | `MEMBER_ID_REQUIRED`           | KIP-394's two-round `JoinGroup` handshake: an empty-`MemberID` round-1 request (v4+) gets a freshly minted ID and this code; the client resends with it. |
| 81   | `GROUP_MAX_SIZE_REACHED`       | The group, or the coordinator-wide group cap, is already at its configured ceiling.                                                                      |
| 82   | `FENCED_INSTANCE_ID`           | KIP-345 static membership: `group.instance.id` maps to a **different** `member.id` than the requester — a displaced or duplicate static instance.        |
| 86   | `GROUP_SUBSCRIBED_TO_TOPIC`    | `OffsetDelete` targeted a `(topic, partition)` a live member still subscribes to — deleting it would rewind that consumer.                               |
| 88   | `UNSTABLE_OFFSET_COMMIT`       | `OffsetFetch` set `RequireStable` (v7+) while the group holds a staged, uncommitted transactional offset. Retriable.                                     |

## Topic and partition admin [#topic-and-partition-admin]

| Code | Error                        | What triggers it                                                                                                                                    |
| ---- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| 36   | `TOPIC_ALREADY_EXISTS`       | `CreateTopics` named a topic that already exists.                                                                                                   |
| 37   | `INVALID_PARTITIONS`         | `CreatePartitions` requested a same-or-lower count, or one above the 256-partition cap; also `CreateTopics`'s `NumPartitions` over that cap.        |
| 38   | `INVALID_REPLICATION_FACTOR` | A request asked for `ReplicationFactor > 1` — replication is internal to Raft, never exposed as separate Kafka replicas.                            |
| 40   | `INVALID_CONFIG`             | An unsupported config value — an invalid `cleanup.policy`, `message.timestamp.type=LogAppendTime`, or an `APPEND`/`SUBTRACT` op on a scalar config. |
| 41   | `NOT_CONTROLLER`             | An admin write landed on a node that isn't the caught-up leader. Retriable — the client retries against the controller.                             |
| 42   | `INVALID_REQUEST`            | A malformed field — most commonly a present-but-empty `transactional.id`, or one failing channel-name validation.                                   |

## Transactions [#transactions]

| Code | Error                                   | What triggers it                                                                                                                                                               |
| ---- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 47   | `INVALID_PRODUCER_EPOCH`                | A `Produce` arrived with an epoch below the live epoch on record — a zombie holding a stale epoch. Non-retriable; the producer must re-run `InitProducerId`.                   |
| 48   | `INVALID_TXN_STATE`                     | A transactional batch arrived in the wrong coordinator state; also reused by `AddPartitionsToTxn`/`AddOffsetsToTxn`/`EndTxn`/`TxnOffsetCommit` for their own state violations. |
| 49   | `INVALID_PRODUCER_ID_MAPPING`           | A KIP-360 request named a `(transactional.id, PID)` pair with no durable record — the ID is new, or was tombstoned since the client last saw it.                               |
| 50   | `INVALID_TRANSACTION_TIMEOUT`           | `TransactionTimeoutMillis` is `<= 0` or exceeds the coordinator-wide ceiling.                                                                                                  |
| 51   | `CONCURRENT_TRANSACTIONS`               | Two state/epoch-transition attempts raced for the same `transactional.id`. Retriable.                                                                                          |
| 53   | `TRANSACTIONAL_ID_AUTHORIZATION_FAILED` | The principal lacks Write on the `transactional.id` resource.                                                                                                                  |
| 55   | `OPERATION_NOT_ATTEMPTED`               | `AddPartitionsToTxn` named a partition that doesn't exist alongside ones that do — the existing ones answer this instead of a false success.                                   |
| 87   | `INVALID_RECORD`                        | A client submitted a control batch — those are broker-internal; the only real producer is the coordinator's own commit/abort marker.                                           |
| 90   | `PRODUCER_FENCED`                       | A KIP-360 `InitProducerId` epoch is strictly above the live durable epoch — the only branch that answers 90.                                                                   |

**KIP-890 transaction protocol V2 is not shipped** — no per-`EndTxn` epoch bump. `EndTxn`
writes a real in-log COMMIT/ABORT marker, but soundness stays bounded to the V1 wire scope in
[Capabilities](/connectors/kafka/reference/capabilities).

## Authorization [#authorization]

| Code | Error                          | What triggers it                                                                                                                                    |
| ---- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| 29   | `TOPIC_AUTHORIZATION_FAILED`   | The principal lacks the required topic ACL — Produce needs Write; Fetch/ListOffsets/OffsetFetch need Read.                                          |
| 30   | `GROUP_AUTHORIZATION_FAILED`   | The principal lacks the required group ACL — OffsetCommit/OffsetDelete/DeleteGroups need Write; Join/Sync/Heartbeat/Leave/DescribeGroups need Read. |
| 31   | `CLUSTER_AUTHORIZATION_FAILED` | The principal lacks Describe on the cluster resource — e.g. `DescribeCluster`(60).                                                                  |

Every authorization deny above is **non-retriable** — re-authenticate or request a policy
grant rather than retry unchanged.

## SASL [#sasl]

| Code | Error                        | What triggers it                                                                                                                                                                                                        |
| ---- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 33   | `UNSUPPORTED_SASL_MECHANISM` | The client's `SASLHandshake` names a mechanism this listener doesn't offer — for example, `OAUTHBEARER` on the plaintext listener (TLS-only). The response still lists supported mechanisms; the connection stays open. |
| 34   | `ILLEGAL_SASL_STATE`         | `SASLAuthenticate` arrived before a successful `SASLHandshake` selected a mechanism.                                                                                                                                    |
| 58   | `SASL_AUTHENTICATION_FAILED` | Credentials didn't validate — unknown user or wrong password/token, deliberately indistinguishable to the client. The connection is closed.                                                                             |

## Security and resource admin [#security-and-resource-admin]

| Code | Error                            | What triggers it                                                                                                                                                                      |
| ---- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 54   | `SECURITY_DISABLED`              | A SCRAM-credential or ACL **mutation** was refused — both are config-managed (`Connectors.Kafka.Credentials`), not runtime-mutable. Also answered when authorization is off entirely. |
| 61   | `DELEGATION_TOKEN_AUTH_DISABLED` | Any delegation-token request — KubeMQ does not implement delegation tokens; switch those principals to SASL/SCRAM or mTLS.                                                            |
| 91   | `RESOURCE_NOT_FOUND`             | `DescribeUserScramCredentials` named a user with no SCRAM credentials configured. Non-retriable.                                                                                      |

## Share groups (preview) [#share-groups-preview]

| Code | Error                         | What triggers it                                                                                                                                                      |
| ---- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 123  | `INVALID_SHARE_SESSION_EPOCH` | An incremental `ShareFetch` arrived for a share session the broker no longer holds — a failover, or the session was reaped. The client resets and reopens at epoch 0. |

## Related [#related]

<Cards>
  <Card title="Capabilities" href="/connectors/kafka/reference/capabilities" description="Every implemented Kafka API key, its version range, and its support status." />

  <Card title="Limits & Rules" href="/connectors/kafka/reference/limits-and-rules" description="The numeric ceilings — partitions, message size, connections, groups — several of these codes enforce." />

  <Card title="Transactions & EOS" href="/connectors/kafka/how-to/transactions" description="Handling the transaction-coordinator error codes in a transactional producer." />

  <Card title="Authentication" href="/connectors/kafka/how-to/authentication" description="SASL/SCRAM, OAUTHBEARER, and mTLS — and the errors each failure mode returns." />
</Cards>
