Monedula

Kafka troubleshooting

TimeoutException (REQUEST_TIMED_OUT)

Kafka error · REQUEST_TIMED_OUT · retriable

org.apache.kafka.common.errors.TimeoutException

The producer gave up on a record because a time limit ran out: send() could not get topic metadata or buffer space within max.block.ms, or the record was not acknowledged within delivery.timeout.ms ("Expiring N record(s)"). The message says which limit fired; fix what made the brokers slow or unreachable instead of only raising the timeout.

Reproduce it in the playground

The moment it happensBlock timed out. t+1.700s

max.block.ms elapsed with the buffer still full, so A3's send FAILS with a BufferExhaustedException (a TimeoutException; the simulator shows it as request_timed_out). p1 goes to error and the held record is dropped - backpressure surfaced the stall instead of buffering without limit.

Open at this step: step 7, Block timed out

What it means

org.apache.kafka.common.errors.TimeoutException covers several timers, and the message tells them apart. "Topic orders not present in metadata after 60000 ms." means send() waited max.block.ms (default 60 seconds) for metadata. "Failed to allocate 1024 bytes within the configured max blocking time 60000 ms" comes from BufferExhaustedException, a subclass: buffer.memory (33554432 bytes by default) was full of records waiting to be sent or acknowledged. In both cases send() blocks the calling thread for up to max.block.ms, then returns a failed Future and calls the callback. "Expiring 1 record(s) for orders-0:120001 ms has passed since batch creation" means the batch was not acknowledged within delivery.timeout.ms (default 2 minutes), the budget for lingering, sending, retries and the ack. Inside that budget, a request with no response after request.timeout.ms (default 30 seconds) is failed as REQUEST_TIMED_OUT ("Disconnected from node 1 due to timeout") and retried, and the broker itself answers REQUEST_TIMED_OUT when an acks=all write waited longer than that timeout for the in-sync replicas. Only the request timeout carries the protocol error REQUEST_TIMED_OUT (code 7); the max.block.ms and delivery.timeout.ms cases are raised by the client and have no broker error code. Scenario 01.2.4 shows the buffer case: the third send blocks, then fails after max.block.ms.

Likely causes, most common first

  1. The topic or partition is not in the metadata. The topic does not exist and auto.create.topics.enable is off on the brokers, the name is misspelled, a record names a partition number the topic does not have ("Partition 7 of topic orders with partition count 6 is not present in metadata after 60000 ms."), or no bootstrap server answers.
  2. Records are produced faster than they are delivered. Slow or distant brokers, client quotas that throttle the producer, or an acks=all path waiting on slow followers let unacknowledged records pile up in buffer.memory. Once it is full, every send() blocks up to max.block.ms and then fails.
  3. The partition leader cannot be reached or does not answer. The client gets metadata from a bootstrap server but cannot reach the leader: advertised.listeners resolve to an address the client cannot route to, a firewall drops the connection, or the leader is overloaded or paused. Requests time out, are retried, and the batch finally expires.
  4. acks=all waits on followers that are in sync but slow. The leader holds the response until every in-sync replica has the batch. If that takes longer than request.timeout.ms, the request times out with REQUEST_TIMED_OUT, from the broker or from the client, and repeated timeouts end in an expired batch. When the ISR is too small instead, the error is NOT_ENOUGH_REPLICAS.

How to fix it

What not to do

Does the client retry it?

The producer already retried or waited. Request timeouts and the broker's REQUEST_TIMED_OUT are retried until delivery.timeout.ms runs out, and a max.block.ms timeout means send() already waited that long for metadata or buffer space. When the exception reaches your callback, those records have failed; sending them again is the application's choice and writes a duplicate if the first attempt did reach the broker.

Configs involved

Reproduce it in the simulator

Sources

Related

All troubleshooting pages