Kafka clients maintain metadata about the cluster topology, including broker addresses, topic partitions, and partition leaders. Proper metadata management is essential for efficient request routing and handling topology changes.
Client Metadata Cache Cluster Info Broker List Topic Metadata orders Cluster ID Controller ID Broker 1: host1:9092 Broker 2: host2:9092 Broker 3: host3:9092 P0: leader=1, ISR=[1,2,3] P1: leader=2, ISR=[2,3,1] P2: leader=3, ISR=[3,1,2] Updated on: - Startup - NotLeaderOrFollower error - metadata.max.age.ms expiry - New topic access
Field Description cluster_idUnique cluster identifier controller_idCurrent controller broker ID brokersList of all brokers with host/port/rack
Field Description node_idUnique broker identifier hostBroker hostname or IP portBroker port (default 9092) rackRack identifier (optional)
Field Description nameTopic name partitionsNumber of partitions is_internalInternal topic flag
Replication factor is derived from the partition replica lists, not returned directly in the metadata response.
Field Description partitionPartition index leaderCurrent leader broker ID leader_epochLeader election epoch replicasAll replica broker IDs isrIn-sync replica broker IDs offline_replicasOffline replica broker IDs
Bootstrap Client Bootstrap Bootstrap Client Client Bootstrap Broker 1 Bootstrap Broker 1 Bootstrap Broker 2 Bootstrap Broker 2 Bootstrap Connect (bootstrap.servers) alt [Connection Success] Connected MetadataRequest (topics=[]) MetadataResponse (full cluster metadata) Cache metadata: - All brokers - All topics (if authorized) - Partition leaders [Connection Failed] Connect (next bootstrap) Connected MetadataRequest MetadataResponse
# Multiple brokers for redundancy
bootstrap.servers =kafka1:9092,kafka2:9092,kafka3:9092
# Client will try brokers in random order
# Only needs ONE successful connection for discovery
Best Practices:
Guideline Rationale List 3+ brokers Redundancy during broker failures Use DNS names Easier maintenance than IPs Include brokers from different racks Survive rack failures Don’t list all brokers Unnecessary, any broker returns full metadata
topics: [TopicName] // Empty for all topics
allow_auto_topic_creation: bool
include_cluster_authorized_operations: bool
include_topic_authorized_operations: bool
partitions: [PartitionMetadata]
offline_replicas: [int32]
Metadata Refresh Triggers Scheduled Error-Driven Explicit metadata.max.age.ms expiry NOT_LEADER_OR_FOLLOWER UNKNOWN_TOPIC_OR_PARTITION (topic expected) LEADER_NOT_AVAILABLE New topic access awaitUpdate() call
# Maximum age before forced refresh
metadata.max.age.ms =300000 # 5 minutes (default)
Check metadata age Age > metadata.max.age.ms? yes no Schedule refresh Error triggers refresh? yes no Immediate refresh Use cached metadata Prefer least-loaded broker Select broker for request Send MetadataRequest Request successful? yes no Update cache Notify waiters Apply backoff Retry with different broker
Metadata Cache Cluster Topics Partitions Timestamps nodes: Map<Integer, Node> controller: Node clusterId: String Map<String, TopicMetadata> Map<TopicPartition, PartitionInfo> lastRefreshMs: long lastSuccessfulRefreshMs: long
Event Action metadata.max.age.ms expiryMark stale, refresh NOT_LEADER_OR_FOLLOWERInvalidate partition UNKNOWN_TOPIC_OR_PARTITIONInvalidate topic Node disconnect Invalidate node
// Find leader for partition
public Node leader ( TopicPartition partition ) {
PartitionInfo info = partitionsByTopicPartition . get ( partition ) ;
// Find all partitions for topic
public List< PartitionInfo > partitionsForTopic ( String topic ) {
return partitionsByTopic . get ( topic ) ;
Error Code Name Cause Client Action 3 UNKNOWN_TOPIC_OR_PARTITIONTopic/partition doesn’t exist Refresh only if the topic is expected to exist 5 LEADER_NOT_AVAILABLELeader election in progress Wait and retry 6 NOT_LEADER_OR_FOLLOWERStale leader info Refresh metadata 29 COORDINATOR_NOT_AVAILABLEGroup coordinator unavailable Retry FindCoordinator
Receive error response Error type? Refresh metadata immediately Retry request to new leader Refresh metadata (if topic expected) Wait for topic creation (if auto-create) Wait (leader election) Refresh metadata Retry request Apply backoff Retry request Return error to caller NOT_LEADER_OR_FOLLOWER Non-retriable UNKNOWN_TOPIC_OR_PARTITION LEADER_NOT_AVAILABLE Other retriable
Leader epoch is a monotonically increasing number that identifies the term of a partition leader. It prevents issues from stale leadership information.
Leader Epoch Timeline Leader Epoch Timeline Partition Leader Broker 1 Broker 2 Broker 1 Broker 3 Leader Epoch 0 1 2 3 0 100 200 250
Producer Old Leader New Leader Producer Producer Old Leader (epoch 5) Old Leader (epoch 5) New Leader (epoch 6) New Leader (epoch 6) Client has stale metadata (leader = old, epoch = 5) ProduceRequest (partition, epoch=5) NOT_LEADER_OR_FOLLOWER (current_epoch=6) Refresh metadata ProduceRequest (partition, epoch=6) Success
# Client rack (for follower fetching)
# Enables rack-aware replica selection
Rack A Rack B Consumer Follower (Broker 2) Leader (Broker 1) Consumer in rack-a fetches from follower in rack-a (Kafka 2.4+, KIP-392) Fetch from rack-local follower Replicate
Producer Metadata Cache Partitioner Producer Producer Metadata Cache Metadata Cache Partitioner Partitioner Get topic metadata TopicMetadata Select partition (key, numPartitions) partition=2 Get leader for partition 2 Broker 3 Send to Broker 3
Consumer Metadata Cache Coordinator Consumer Consumer Metadata Cache Metadata Cache Coordinator Coordinator Get partitions for topics [P0, P1, P2, ...] JoinGroup(topics) Assignment(P0, P2) Get leaders for P0, P2 P0→Broker1, P2→Broker3 Fetch from assigned partitions
Optimization Configuration Increase refresh interval metadata.max.age.ms=600000Request specific topics Don’t request all topics Cache locally Avoid redundant lookups
Kafka batches metadata requests when multiple threads need updates:
Thread 1 Thread 2 Metadata Manager Broker Thread 1 Thread 1 Thread 2 Thread 2 Metadata Manager Metadata Manager Broker Broker requestUpdate() requestUpdate() Coalesce requests into single batch MetadataRequest MetadataResponse Metadata updated Metadata updated
Producer client metrics are reported under the producer-metrics group.
Metric Description Alert Threshold metadata-ageAge in seconds of the current producer metadata > 2 × metadata.max.age.ms / 1000 metadata-wait-time-ns-totalCumulative time spent waiting for metadata (ns) Sustained increase in rate
# Enable metadata debug logging
log4j.logger.org.apache.kafka.clients.Metadata =DEBUG
log4j.logger.org.apache.kafka.clients.NetworkClient =DEBUG
Common issues:
Symptom Cause Solution Frequent refreshes Many NOT_LEADER errors Check cluster stability Stale metadata Long metadata.max.age.ms Reduce refresh interval Missing topics Authorization issues Check ACLs Wrong broker count Partial visibility Check bootstrap servers
Feature Minimum Version Basic metadata 0.8.0 Rack information 0.10.0 Leader epoch 0.11.0 Offline replicas 1.0.0 Authorized operations 2.3.0