Apache Kafka Knowledge Patch
Use this skill when upgrading, configuring, operating, extending, or developing
against Apache Kafka. Start with the breaking-change checks below, then open the
topic reference that matches the work.
Reference index
| Reference |
Topics |
| upgrades-and-compatibility.md |
Rolling upgrades, feature finalization, metadata downgrade boundaries, runtimes, layouts, logging, and release safety fixes |
| brokers-kraft-and-storage.md |
Broker and controller configuration, KRaft, coordinators, log cleaning, retention, remote logs, tiered storage, and log directories |
| clients-groups-and-security.md |
Producer, consumer, Admin, transactions, group protocols, share groups, OAuth, callbacks, and security extensions |
| streams.md |
Streams migration, rebalance protocol, state stores, RocksDB, handlers, headers, metrics, testing, and Scala |
| connect-mirrormaker-and-tools.md |
Connect APIs and plugins, MirrorMaker, command-line migrations, formatters, decoders, converters, and benchmarks |
| observability-and-metrics.md |
JMX renames, metric identity and semantics, plugin telemetry, feature levels, coordinator buffers, and storage visibility |
Breaking changes first
Upgrade only from a supported KRaft state
- Kafka brokers no longer support ZooKeeper mode. Migrate to KRaft before the
broker upgrade.
- Ensure software and metadata versions are at least 3.3. Move older KRaft
clusters to 3.9.x before proceeding.
- Clients, Streams applications, and Connect must be at least 2.1. Exactly-once
Streams processing requires brokers 2.5 or later.
- Roll brokers one at a time, verify the cluster, and only then finalize the
target feature level.
- Finalizing 4.0 or 4.3 crosses a metadata downgrade boundary. Do not promise a
rollback across either boundary.
Meet the runtime floor
- Run clients and Streams applications on Java 11 or later.
- Run brokers, Connect, and Kafka tools on Java 17 or later.
- Scala 2.12 is unsupported.
- KRaft configuration files live in the common
config directory, not
config/kraft.
- Convert Log4j configuration to Log4j2 and replace
KafkaLog4jAppender with
the Log4j2 Kafka appender.
Replace removed broker settings
- Remove
log.message.format.version, message.format.version,
offsets.commit.required.acks, and log.message.timestamp.difference.max.ms.
- Replace the timestamp-difference limit with
log.message.timestamp.before.max.ms and
log.message.timestamp.after.max.ms.
- Replace
metrics.jmx.blacklist/metrics.jmx.whitelist with
metrics.jmx.exclude/metrics.jmx.include.
- Replace
delegation.token.master.key with
delegation.token.secret.key.
- Replace
remote.log.manager.thread.pool.size with
remote.log.manager.follower.thread.pool.size.
- Migrate login-module policy from
org.apache.kafka.disallowed.login.modules to
org.apache.kafka.allowed.login.modules.
Update client APIs before compiling
- Replace
Consumer.poll(long) with poll(Duration).
- Replace single-partition
committed(...) calls with the
Set<TopicPartition> overloads.
- Replace
Admin.alterConfigs() with incrementalAlterConfigs().
- Use
GroupState instead of ConsumerGroupState.
- Use
NotLeaderOrFollowerException instead of
NotLeaderForPartitionException.
- Replace removed partitioners rather than depending on
DefaultPartitioner, UniformStickyPartitioner, or onNewBatch().
- Use the map-based
listConsumerGroupOffsets API and the renamed
topic-result accessors.
- Treat
TimeoutException and TransactionAbortableException as reasons to
abort a transaction.
Audit changed defaults
- Producer
linger.ms defaults to 5.
log.message.timestamp.after.max.ms defaults to one hour, rejecting records
farther in the future when using create-time timestamps.
segment.bytes and log.segment.bytes have a 1 MB minimum.
num.recovery.threads.per.data.dir defaults to 2.
- New clusters enable Eligible Leader Replicas by default.
- Group assignment update intervals default to one second.
remote.log.metadata.topic.min.isr defaults to 2.
Handle Streams state as a compatibility boundary
- Prefer the first maintenance release when the base release has a documented
critical Streams defect.
- Before downgrading from a release that changed RocksDB or local state format,
stop every instance, delete local state, and restore from changelog topics.
- Do not mechanically rename
transformValues() to processValues(); follow
the migration behavior and require the maintenance fix.
- Move from the old Processor and transformer APIs to the current Processor
API before upgrading.
- Migrate nested
KafkaStreams.CloseOptions to the top-level
org.apache.kafka.streams.CloseOptions.
- Plan migration from
kafka-streams-scala to the Java Streams API before
Kafka 5.0.
High-value operational guidance
Finalize features deliberately
Inspect finalized and supported feature levels on every node during mixed
deployments. Finalize only after all brokers run successfully at the new
software version. Protocol behavior can change at finalization even when the
rolling restart itself appeared uneventful.
The consumer, Streams, and share protocols are governed by group.version,
streams.version, and share.version. Move away from
group.coordinator.rebalance.protocols, which is scheduled for removal.
Size internal topics for small clusters
Before first share-group use on a cluster with fewer than three brokers, set
both of these values; the internal topic is otherwise auto-created with
three-broker assumptions:
share.coordinator.state.topic.replication.factor=1
share.coordinator.state.topic.min.isr=1
Treat share groups as work queues
Share-group consumers cooperatively process individual records rather than
owning partitions exclusively. Use per-record acknowledgement, delivery
attempts, strict or batch-optimized fetch limits, lock renewal, delivery-count
limits, and record-lock limits according to the workload. Do not assume
consumer-group ordering semantics.
Keep callbacks non-blocking and transaction-safe
Never call KafkaProducer.flush() from a producer callback; the producer now
rejects that deadlock-prone pattern. Return promptly. In transactional code,
abort on abortable or timeout failures instead of retrying the transaction and
risk producing duplicates.
Configure OAuth endpoints explicitly
Allow token and JWKS endpoints through the
org.apache.kafka.sasl.oauthbearer.allowed.urls system property. Its default is
empty. Update callback-handler package names, and choose JWT bearer or client
assertion authentication when the identity provider requires it.
Use coordinator and remote-log controls intentionally
Bound reusable and append buffers for group and share coordinators, size
background assignment work, and review the one-second assignment intervals.
For remote logs, set the metadata topic minimum ISR, separate metadata Admin
client properties under remote.log.metadata.admin., and use the follower pool
setting instead of the deprecated generic pool.
Plan log-directory maintenance
Use log-directory cordoning to remove a directory from ordinary placement
workflows before maintenance. With tiered storage, optionally bootstrap a new
follower at the earliest pending-upload offset and query that boundary through
the matching ListOffsets timestamp type.
High-value Streams features
Choose the rebalance protocol consciously
The broker-driven Streams protocol is production-ready in the appropriate
maintenance line. Migration from classic groups requires the documented safety
fix. Protocol-owned session, heartbeat, and standby-replica settings are group
configuration, not client configuration.
Use a fresh application identity when required, understand which topology
changes are supported, and monitor the Streams-specific task assignment,
revocation, and loss latency metrics after migration.
Use production exception handling and dead-letter queues
Configure a production DLQ with:
errors.dead.letter.queue.topic.name=streams-errors
Custom production handlers must create DLQ records themselves. Use the current
handler response and method names. Global-store processing handlers require an
explicit opt-in and do not yet support DLQ output.
Opt in to header-aware stores carefully
Use the WithHeaders suppliers and builders for Processor API stores. For
supported DSL stores, set dsl.store.format=HEADERS or select store suppliers
per operator. Header propagation is operator-specific; several aggregations,
joins, tables, and buffers currently write empty or dropped headers.
Rolling upgrades are supported, but migrated local data creates a downgrade
boundary. Clear local state before returning to an older release.
Understand state-store offset durability
Built-in stores can keep changelog offsets inside the store. RocksDB persists
them when the memtable reaches an SST file or on a clean close, not at every
commit. After an unclean low-traffic shutdown, automatic task reinitialization
and full restore can occur without data loss.
Implementation checklist
- Determine the broker, metadata, client, Connect, and Streams versions.
- Open the upgrade reference and identify finalization and downgrade limits.
- Search configuration for removed, renamed, deprecated, and changed-default
settings.
- Compile clients and extensions against the target APIs.
- Check command invocations and custom tool interfaces.
- Review local-state and RocksDB downgrade procedures.
- Update dashboards for renamed metrics, tags, domains, and ratio semantics.
- Exercise group migrations, transaction abort paths, callbacks, and
maintenance rollback in a non-production environment.
- Prefer the documented maintenance release when a base release carries a
critical correctness, deadlock, or resource-leak fix.
1---2name: apache-kafka-knowledge-patch3description: Apache Kafka4license: MIT5---678# Apache Kafka Knowledge Patch910Use this skill when upgrading, configuring, operating, extending, or developing11against Apache Kafka. Start with the breaking-change checks below, then open the12topic reference that matches the work.1314## Reference index1516| Reference | Topics |17| --- | --- |18| [upgrades-and-compatibility.md](references/upgrades-and-compatibility.md) | Rolling upgrades, feature finalization, metadata downgrade boundaries, runtimes, layouts, logging, and release safety fixes |19| [brokers-kraft-and-storage.md](references/brokers-kraft-and-storage.md) | Broker and controller configuration, KRaft, coordinators, log cleaning, retention, remote logs, tiered storage, and log directories |20| [clients-groups-and-security.md](references/clients-groups-and-security.md) | Producer, consumer, Admin, transactions, group protocols, share groups, OAuth, callbacks, and security extensions |21| [streams.md](references/streams.md) | Streams migration, rebalance protocol, state stores, RocksDB, handlers, headers, metrics, testing, and Scala |22| [connect-mirrormaker-and-tools.md](references/connect-mirrormaker-and-tools.md) | Connect APIs and plugins, MirrorMaker, command-line migrations, formatters, decoders, converters, and benchmarks |23| [observability-and-metrics.md](references/observability-and-metrics.md) | JMX renames, metric identity and semantics, plugin telemetry, feature levels, coordinator buffers, and storage visibility |2425## Breaking changes first2627### Upgrade only from a supported KRaft state2829- Kafka brokers no longer support ZooKeeper mode. Migrate to KRaft before the30 broker upgrade.31- Ensure software and metadata versions are at least 3.3. Move older KRaft32 clusters to 3.9.x before proceeding.33- Clients, Streams applications, and Connect must be at least 2.1. Exactly-once34 Streams processing requires brokers 2.5 or later.35- Roll brokers one at a time, verify the cluster, and only then finalize the36 target feature level.37- Finalizing 4.0 or 4.3 crosses a metadata downgrade boundary. Do not promise a38 rollback across either boundary.3940### Meet the runtime floor4142- Run clients and Streams applications on Java 11 or later.43- Run brokers, Connect, and Kafka tools on Java 17 or later.44- Scala 2.12 is unsupported.45- KRaft configuration files live in the common `config` directory, not46 `config/kraft`.47- Convert Log4j configuration to Log4j2 and replace `KafkaLog4jAppender` with48 the Log4j2 Kafka appender.4950### Replace removed broker settings5152- Remove `log.message.format.version`, `message.format.version`,53 `offsets.commit.required.acks`, and `log.message.timestamp.difference.max.ms`.54- Replace the timestamp-difference limit with55 `log.message.timestamp.before.max.ms` and56 `log.message.timestamp.after.max.ms`.57- Replace `metrics.jmx.blacklist`/`metrics.jmx.whitelist` with58 `metrics.jmx.exclude`/`metrics.jmx.include`.59- Replace `delegation.token.master.key` with60 `delegation.token.secret.key`.61- Replace `remote.log.manager.thread.pool.size` with62 `remote.log.manager.follower.thread.pool.size`.63- Migrate login-module policy from64 `org.apache.kafka.disallowed.login.modules` to65 `org.apache.kafka.allowed.login.modules`.6667### Update client APIs before compiling6869- Replace `Consumer.poll(long)` with `poll(Duration)`.70- Replace single-partition `committed(...)` calls with the71 `Set<TopicPartition>` overloads.72- Replace `Admin.alterConfigs()` with `incrementalAlterConfigs()`.73- Use `GroupState` instead of `ConsumerGroupState`.74- Use `NotLeaderOrFollowerException` instead of75 `NotLeaderForPartitionException`.76- Replace removed partitioners rather than depending on77 `DefaultPartitioner`, `UniformStickyPartitioner`, or `onNewBatch()`.78- Use the map-based `listConsumerGroupOffsets` API and the renamed79 topic-result accessors.80- Treat `TimeoutException` and `TransactionAbortableException` as reasons to81 abort a transaction.8283### Audit changed defaults8485- Producer `linger.ms` defaults to `5`.86- `log.message.timestamp.after.max.ms` defaults to one hour, rejecting records87 farther in the future when using create-time timestamps.88- `segment.bytes` and `log.segment.bytes` have a 1 MB minimum.89- `num.recovery.threads.per.data.dir` defaults to `2`.90- New clusters enable Eligible Leader Replicas by default.91- Group assignment update intervals default to one second.92- `remote.log.metadata.topic.min.isr` defaults to `2`.9394### Handle Streams state as a compatibility boundary9596- Prefer the first maintenance release when the base release has a documented97 critical Streams defect.98- Before downgrading from a release that changed RocksDB or local state format,99 stop every instance, delete local state, and restore from changelog topics.100- Do not mechanically rename `transformValues()` to `processValues()`; follow101 the migration behavior and require the maintenance fix.102- Move from the old Processor and transformer APIs to the current Processor103 API before upgrading.104- Migrate nested `KafkaStreams.CloseOptions` to the top-level105 `org.apache.kafka.streams.CloseOptions`.106- Plan migration from `kafka-streams-scala` to the Java Streams API before107 Kafka 5.0.108109## High-value operational guidance110111### Finalize features deliberately112113Inspect finalized and supported feature levels on every node during mixed114deployments. Finalize only after all brokers run successfully at the new115software version. Protocol behavior can change at finalization even when the116rolling restart itself appeared uneventful.117118The consumer, Streams, and share protocols are governed by `group.version`,119`streams.version`, and `share.version`. Move away from120`group.coordinator.rebalance.protocols`, which is scheduled for removal.121122### Size internal topics for small clusters123124Before first share-group use on a cluster with fewer than three brokers, set125both of these values; the internal topic is otherwise auto-created with126three-broker assumptions:127128```properties129share.coordinator.state.topic.replication.factor=1130share.coordinator.state.topic.min.isr=1131```132133### Treat share groups as work queues134135Share-group consumers cooperatively process individual records rather than136owning partitions exclusively. Use per-record acknowledgement, delivery137attempts, strict or batch-optimized fetch limits, lock renewal, delivery-count138limits, and record-lock limits according to the workload. Do not assume139consumer-group ordering semantics.140141### Keep callbacks non-blocking and transaction-safe142143Never call `KafkaProducer.flush()` from a producer callback; the producer now144rejects that deadlock-prone pattern. Return promptly. In transactional code,145abort on abortable or timeout failures instead of retrying the transaction and146risk producing duplicates.147148### Configure OAuth endpoints explicitly149150Allow token and JWKS endpoints through the151`org.apache.kafka.sasl.oauthbearer.allowed.urls` system property. Its default is152empty. Update callback-handler package names, and choose JWT bearer or client153assertion authentication when the identity provider requires it.154155### Use coordinator and remote-log controls intentionally156157Bound reusable and append buffers for group and share coordinators, size158background assignment work, and review the one-second assignment intervals.159For remote logs, set the metadata topic minimum ISR, separate metadata Admin160client properties under `remote.log.metadata.admin.`, and use the follower pool161setting instead of the deprecated generic pool.162163### Plan log-directory maintenance164165Use log-directory cordoning to remove a directory from ordinary placement166workflows before maintenance. With tiered storage, optionally bootstrap a new167follower at the earliest pending-upload offset and query that boundary through168the matching `ListOffsets` timestamp type.169170## High-value Streams features171172### Choose the rebalance protocol consciously173174The broker-driven Streams protocol is production-ready in the appropriate175maintenance line. Migration from classic groups requires the documented safety176fix. Protocol-owned session, heartbeat, and standby-replica settings are group177configuration, not client configuration.178179Use a fresh application identity when required, understand which topology180changes are supported, and monitor the Streams-specific task assignment,181revocation, and loss latency metrics after migration.182183### Use production exception handling and dead-letter queues184185Configure a production DLQ with:186187```properties188errors.dead.letter.queue.topic.name=streams-errors189```190191Custom production handlers must create DLQ records themselves. Use the current192handler response and method names. Global-store processing handlers require an193explicit opt-in and do not yet support DLQ output.194195### Opt in to header-aware stores carefully196197Use the `WithHeaders` suppliers and builders for Processor API stores. For198supported DSL stores, set `dsl.store.format=HEADERS` or select store suppliers199per operator. Header propagation is operator-specific; several aggregations,200joins, tables, and buffers currently write empty or dropped headers.201202Rolling upgrades are supported, but migrated local data creates a downgrade203boundary. Clear local state before returning to an older release.204205### Understand state-store offset durability206207Built-in stores can keep changelog offsets inside the store. RocksDB persists208them when the memtable reaches an SST file or on a clean close, not at every209commit. After an unclean low-traffic shutdown, automatic task reinitialization210and full restore can occur without data loss.211212## Implementation checklist2132141. Determine the broker, metadata, client, Connect, and Streams versions.2152. Open the upgrade reference and identify finalization and downgrade limits.2163. Search configuration for removed, renamed, deprecated, and changed-default217 settings.2184. Compile clients and extensions against the target APIs.2195. Check command invocations and custom tool interfaces.2206. Review local-state and RocksDB downgrade procedures.2217. Update dashboards for renamed metrics, tags, domains, and ratio semantics.2228. Exercise group migrations, transaction abort paths, callbacks, and223 maintenance rollback in a non-production environment.2249. Prefer the documented maintenance release when a base release carries a225 critical correctness, deadlock, or resource-leak fix.