pinpoint-apm/pinpoint · error
onFailure
Error message
{} onFailure:{} What it means
KafkaCallbacks.loggingCallback returns a BiConsumer attached to Kafka send futures; when the KafkaTemplate.send future completes with a Throwable, the callback logs this warning containing the callback name and throwable message. It indicates a Kafka produce failure (message may not have been persisted to the topic).
Solutions
- Read the logged throwable for the exact Kafka error (TimeoutException, NotLeaderForPartition, RecordTooLargeException, etc.).
- Verify bootstrap.servers connectivity and topic existence/ACLs from the collector host.
- Increase delivery.timeout.ms / request.timeout.ms or reduce batch pressure under load.
- Add a producer failure metric/retry policy or dead-letter path for lost records.
Example fix
// before: failure only logged, data silently lost
kafkaTemplate.send(topic, record, KafkaCallbacks.loggingCallback("span", log));
// after: handle failure explicitly
kafkaTemplate.send(topic, record)
.whenComplete(KafkaCallbacks.loggingCallback("span", log));
// plus producer config: delivery.timeout.ms=120000, retries=10 Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before send
try (AdminClient admin = AdminClient.create(props)) {
if (!admin.describeTopics(Collections.singletonList(topic)).allTopicNames().get().containsKey(topic)) {
throw new IllegalStateException("topic missing: " + topic);
}
} Try / catch
kafkaTemplate.send(topic, key, value)
.whenComplete((result, throwable) -> {
if (throwable != null) {
logger.warn("send onFailure:{}", throwable.getMessage(), throwable);
// deadLetter(topic, key, value, throwable); // persist for replay
}
}); Prevention
- Verify bootstrap.servers, topic existence, and produce ACLs before deploying.
- Set sane producer timeouts (delivery.timeout.ms, request.timeout.ms) and retries.
- Check message sizes against max.request.size to avoid RecordTooLargeException.
- Monitor Kafka producer error metrics; the callback only logs, it does not recover.
When it happens
Trigger: The ListenableFuture/CompletableFuture from a Kafka producer send completes exceptionally — broker unreachable, record too large, serialization failure, timeout, or topic authorization failure.
Common situations: Kafka broker down or DNS/service name wrong in pinot-kafka config; acks/timeout settings too aggressive; message exceeding max.request.size; topic missing or ACLs deny produce.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/59d0e023a30b8953.
Report an issue: GitHub.
Appendix: source
Thrown at pinot/pinot-kafka/src/main/java/com/navercorp/pinpoint/pinot/kafka/util/KafkaCallbacks.java:15
package com.navercorp.pinpoint.pinot.kafka.util;
import org.apache.logging.log4j.Logger;
import org.springframework.kafka.support.SendResult;
import java.util.function.BiConsumer;
public final class KafkaCallbacks {
public static <T> BiConsumer<SendResult<String, T>, Throwable> loggingCallback(String name, Logger logger) {
return new BiConsumer<>() {
@Override
public void accept(SendResult<String, T> result, Throwable throwable) {
if (throwable != null) {
logger.warn("{} onFailure:{}", name, throwable.getMessage(), throwable);
} else {
if (logger.isDebugEnabled()) {
logger.debug("{} onSuccess:{}", name, result);
}
}
}
};
}
}
View on GitHub (pinned to 744c3d3075)