apache/kafka · error · TimeoutException

Failed to update metadata after {timeoutMs} ms.

Error message

Failed to update metadata after {timeoutMs} ms.

What it means

Thrown by ProducerMetadata.awaitUpdate when the metadata version does not advance past the requested version before the Timer expires. The producer blocks on metadata before it can partition and append a record; this exception means that wait failed within the configured budget (typically max.block.ms). It is a client-side timeout distinct from per-request timeouts — it specifically covers metadata refresh, not produce acknowledgement.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/producer/internals/ProducerMetadata.java:163

            log.debug("Removing unused topic {} from the metadata list, expiryMs {} now {}", topic, expireMs, nowMs);
            return false;
        }
        return true;
    }

    /**
     * Wait for metadata update until the current version is larger than the last version we know of
     */
    public synchronized void awaitUpdate(final int lastVersion, final Timer timer) throws InterruptedException {
        while (true) {
            // Throw fatal exceptions, if there are any. Recoverable topic errors will be handled by the caller.
            maybeThrowFatalException();
            if (updateVersion() > lastVersion || isClosed())
                break;

            timer.update();
            if (timer.isExpired())
                throw new TimeoutException("Failed to update metadata after " + timer.timeoutMs() + " ms.");

            wait(timer.remainingMs());
        }

        if (isClosed())
            throw new KafkaException("Requested metadata update after close");
    }

    @Override
    public synchronized void update(int requestVersion, MetadataResponse response, boolean isPartialUpdate, long nowMs) {
        super.update(requestVersion, response, isPartialUpdate, nowMs);
        errors = response.errors();

        // Remove all topics in the response that are in the new topic set. Note that if an error was encountered for a
        // new topic's metadata, then any work to resolve the error will include the topic in a full metadata update.
        if (!newTopics.isEmpty()) {
            for (MetadataResponse.TopicMetadata metadata : response.topicMetadata()) {
                newTopics.remove(metadata.topic());

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Verify bootstrap.servers is correct, reachable (telnet/nc to port 9092), and points at live brokers.
  2. Increase max.block.ms if the cluster legitimately needs longer (e.g. slow auto-topic-creation or large clusters).
  3. Pre-create topics on the broker, or auto-create them before the producer starts, so metadata returns cleanly.
  4. Check broker logs / clients metrics 'metadata-age' and connection-success-rate; fix auth (SASL/SSL) if connections fail.
  5. Ensure the client can reach the advertised.listeners addresses brokers return, not just the bootstrap ones.

Example fix

// before
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "wrong-host:9092");
producer.send(new ProducerRecord<>("orders", k, v));

// after
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-1:9092,kafka-2:9092");
// and pre-create topic 'orders' on the broker
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify reachability before relying on metadata under load.
try (Socket s = new Socket()) {
    s.connect(new InetSocketAddress(brokerHost, brokerPort), 1000);
} catch (IOException e) {
    // broker unreachable; do not attempt produce that depends on fresh metadata
}

Try / catch

try {
    producer.send(record);
} catch (org.apache.kafka.common.errors.TimeoutException te) {
    // metadata could not be refreshed within max.block.ms
    // back off, investigate broker/controller/network, then retry
} catch (InterruptedException ie) {
    Thread.currentThread().interrupt();
}

Prevention

When it happens

Trigger: KafkaProducer.send() or an explicit metadata touch triggering awaitUpdate() while no broker responds to the MetadataRequest within max.block.ms (default 60s). Common when the bootstrap brokers are unreachable, all brokers are down, the topic is AUTO_CREATE and the controller cannot create it in time, or a partition's leader is being elected and metadata keeps returning errors.

Common situations: Wrong bootstrap.servers (typo, stale DNS, firewalled port 9092); brokers reachable but SASL/SSL handshake failing silently; a topic referenced by send() does not exist and auto.create.topics.enable is false on the broker; KRaft controller quorum unhealthy; cluster under rebalance/partition reassignment; DNS resolves to a dead VIP.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/c52e15f5c9d501bf.json. Report an issue: GitHub.