Kafka binder health-check consumer failures return DOWN without logging the exception

Fermée
#3,329 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

  • #3331 par @Sanskar121543 — fermée sans fusion

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
25/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
À l'abandon
Stack technique
java, kafka, spring-boot

Piste de recherche

Start with AbstractKafkaBinderHealthIndicator.buildTopicsHealth() and safelyBuildTopicsHealth() in the Kafka binder core; the issue identifies both as paths that convert failures into health results without logging. Read the existing logging conventions for health indicator failures, then check that the returned health status remains DOWN and the underlying exception is logged without repeated probe failures flooding logs.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Describe the issue

The Kafka binder can report DOWN because its health-check metadata consumer cannot be constructed, without logging the failure or its underlying cause. Meanwhile, application startup and the actual listener containers can succeed.

The health endpoint exposes only:

org.apache.kafka.common.KafkaException: Failed to construct kafka consumer

In the case we investigated, the underlying exception was:

java.lang.IllegalStateException: No delegate deserializer configured

This report is about missing error logging, not about accepting an incomplete deserializer configuration. Returning DOWN is appropriate, but the diagnostic cause should also be available in the application logs.

To Reproduce

The following is a reduced configuration illustrating the triggering setup: use ErrorHandlingDeserializer at binder scope and configure its value delegate only at binding scope.

  1. Start a Spring Boot application with Actuator, the web starter, the Spring Cloud Stream Kafka binder, and a reachable plaintext Kafka broker.

  2. Register a simple function:

    @Bean
    public Consumer<String> consume() {
        return value -> {};
    }
    
  3. Configure the binder and binding:

    management:
      endpoint:
        health:
          show-details: always
    
    spring:
      cloud:
        function:
          definition: consume
        stream:
          bindings:
            consume-in-0:
              destination: health-repro
              group: health-repro
              consumer:
                useNativeDecoding: true
          kafka:
            binder:
              brokers: localhost:9092
              consumer-properties:
                key.deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
                value.deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
                spring.deserializer.key.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
            bindings:
              consume-in-0:
                consumer:
                  configuration:
                    spring.deserializer.value.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
    
  4. Let the application start, then call GET /actuator/health.

  5. Observe that binder health is DOWN with Failed to construct kafka consumer, despite the listener container running. No corresponding health-check exception or nested cause is logged at WARN/ERROR.

The failure was reproduced in a multi-binder application and an HTTP integration test. The reduced single-binder example above is provided to illustrate the configuration pattern; it has not been run as a separate sample project.

Version of the framework

  • Spring Boot: 4.1.2
  • Spring Cloud release train: 2025.1.4
  • Spring Cloud Stream: 5.0.4
  • Spring Cloud Stream Kafka binder and Kafka binder core: 5.0.4
  • Spring for Apache Kafka (spring-kafka): 4.1.2
  • Apache Kafka clients: 4.2.2
  • Java: Eclipse Temurin 25.0.5

The Spring Boot, Spring Cloud, and Java settings were checked against the application build configuration. The packaged application JAR confirms the resolved Spring Boot, Spring Cloud Stream, Spring Kafka, and Kafka client versions. The failing HTTP integration test ran on Java 25.0.5. The exception-to-health-result handling was also checked in the released v5.0.4 source and on the main branch.

Expected behavior

When metadata consumer construction fails, log an ERROR identifying the Kafka binder health check and include the exception and full cause chain. If WARN is the project's convention for health-indicator failures, that would still be substantially more actionable than the current silent conversion.

The health endpoint should continue returning DOWN; startup need not fail solely because of a lazily created health-check consumer. Logging is expected when the health check actually encounters the failure, not necessarily during startup.

Please consider logging on the initial failure/state transition or otherwise deduplicating/rate-limiting repeated failures, so regular health probes do not flood logs with identical stack traces. There is no need to log configuration maps or credentials.

Additional context

The relevant code paths appear to be:

Because the exception is handled inside the indicator, the exception-logging path in the superclass is not reached. Health details retain the outer exception message rather than the useful nested deserializer error.

Supplying spring.deserializer.value.delegate.class at binder scope resolves this particular configuration failure, while bindings can still override the delegate as needed. However, that workaround does not address the missing diagnostics for this or other health-check failures.

I searched existing open issues for the exact error, missing delegates, the health indicator class, and health-check logging. Related but apparently different reports include spring-cloud/spring-cloud-stream#2958 (binary compatibility), spring-cloud/spring-cloud-stream#3042 (custom multi-binder indicators), and spring-cloud/spring-cloud-stream#3138 (Kafka Streams/DNS connectivity).

Langage dominant
Java
Étoiles
1.1k
Forks
653
Merge moyen
12 h 59 min
PR mergées (30 j)
7

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de spring-cloud/spring-cloud-stream

Toutes les issues de spring-cloud/spring-cloud-stream

Issues similaires

Plus d'issues Java

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.