Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

ConsulDiscoveryClient.getServices() throws NPE when Consul has no leader, and the gateway's discovery routes stay empty afterwards

Cerrado
#1,040 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Ya se ha fusionado un pull request relacionado.

  • #1041 de @ryanjbaxter — fusionado

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
java, spring, spring-boot

Línea de trabajo

Start with ConsulDiscoveryClient.getServices() in ConsulDiscoveryClient.java and ConsulReactiveDiscoveryClient.getServices() in ConsulReactiveDiscoveryClient.java; inspect how a null catalog response and the resulting failure are handled. Then trace how discovery results reach the route locator, including whether errors or empty results replace existing routes. Done means a Consul response without a leader does not turn into a misleading empty service list or leave discovery routes unavailable after leadership returns; add or run focused tests for those cases.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

waiting-for-triage

After a Consul leader election, a Spring Cloud Gateway app that uses discovery-based routes loses all of its routes and keeps returning 404 until the Consul catalog changes again.

While Consul has no leader, GET /v1/catalog/services returns 500 "No cluster leader". ConsulDiscoveryClient.getServices() then calls keySet() on a null body:

Map<String, List<String>> catalogServices = client
	.getCatalogServices(properties.getAclToken(), QueryParams.DEFAULT)
	.getBody();
return new ArrayList<>(catalogServices.keySet());

ConsulReactiveDiscoveryClient.getServices() logs the exception and returns Flux.empty(), so the discovery route locator rebuilds its routes from an empty service list:

ERROR ConsulReactiveDiscoveryClient : Error getting services from Consul.
java.lang.NullPointerException: Cannot invoke "java.util.Map.keySet()" because "catalogServices" is null
	at org.springframework.cloud.consul.discovery.ConsulDiscoveryClient.getServices(ConsulDiscoveryClient.java:104)
	at org.springframework.cloud.consul.discovery.reactive.ConsulReactiveDiscoveryClient.lambda$getServices$2(ConsulReactiveDiscoveryClient.java:74)

Once a leader is elected, nothing rebuilds the routes, because the catalog index doesn't change. In our case the gateway returned 404 for every /services/<app>/** route for more than 5 minutes after the election. Registering any service (which changes the catalog index) brought the routes back about 3 seconds later.

How we hit it: a JHipster 9.4.0 microservices app (Spring Boot 4.1.1, Spring Cloud 2025.1.3, spring-cloud-consul 5.0.3) on a kind cluster, with a 3-server Consul 2.1.0 StatefulSet and a reactive gateway using discovery routes.

  1. Deploy the gateway and two services, all registered with Consul, and check that /services/<app>/** routes work.
  2. Run kubectl rollout restart statefulset/consul so Consul elects a new leader.
  3. While there's no leader, the gateway logs the NPE above. After the rollout, every discovery route returns 404 until something changes the catalog.

The code is the same in v5.0.4 and on main (getAllInstances() has the same unchecked getBody()).

I'd expect getServices() to throw an exception that says Consul couldn't answer, rather than an NPE. I'd also expect the reactive client not to turn that failure into an empty service list, since an empty list looks like a valid answer and wipes every route. Either keeping the last known services or propagating the error so the route locator keeps its current routes would avoid the outage.

Lenguaje dominante
Java
Estrellas
821
Forks
540
Merge medio
13 h 41 min
PR fusionados (30 d)
17

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de spring-cloud/spring-cloud-consul

Todos los issues de spring-cloud/spring-cloud-consul

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.