Skip to content

Fixes potential NPE in getServices and getAllInstances - #1041

Merged
ryanjbaxter merged 1 commit into
spring-cloud:5.0.xfrom
ryanjbaxter:fix-npe-in-getservices
Oct 30, 2026
Merged

ryanjbaxter merged 1 commit into
spring-cloud:5.0.xfrom
ryanjbaxter:fix-npe-in-getservices

Conversation

@ryanjbaxter

Copy link
Copy Markdown
Contributor

Fixes #1040

@spencergibb spencergibb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming PR builds cleanly, LGTM

@mraible

mraible commented Oct 30, 2026

Copy link
Copy Markdown

Thanks, @ryanjbaxter! I tested this PR (adf81bb, installed locally as 5.0.5-SNAPSHOT) against 5.0.4 with a reactive Spring Cloud Gateway that uses discovery routes (Spring Boot 4.1.1, Spring Cloud 2025.1.4) and Consul 2.1.0: three servers with persistent data, plus a client agent the gateway talks to.

To reproduce the issue, I stopped two of the three servers (no quorum, so the agent answers 500 "No cluster leader"), triggered a route refresh with POST /actuator/gateway/refresh (standing in for the catalog change the watch saw during the election in Kubernetes), started the servers again, and polled a discovery route every second for three minutes.

5.0.4 This PR
Refresh with no leader NullPointerException IllegalStateException: Consul did not return a service catalog
Discovery route during the outage 404 (all routes wiped) 503 after 8-10 seconds (route kept)
After a leader is elected 200, only because another catalog change triggered a refresh 200 right away, no refresh needed
404s while polling 8 0

ConsulReactiveDiscoveryClientTests passes too (11 tests). With the error propagated, the gateway keeps its last good routes, so the "routes stay empty until the catalog changes" part of the issue can't happen anymore.

Two notes:

  • During an outage, route requests now wait for Consul and return 503 instead of an immediate 404. I think that's the right behavior.
  • ConsulReactiveDiscoveryClient now propagates errors to every caller, not just the gateway, so code that relied on an empty Flux will see an error instead. Might be worth a mention in the release notes.

LGTM!

@ryanjbaxter
ryanjbaxter merged commit a431f19 into spring-cloud:5.0.x Oct 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

4 participants