DEV Community

Cover image for Lessons Learned: CompletableFuture Security and Kafka Topic Grouping in Microservices
Jayesh Shinde
Jayesh Shinde

Posted on

Lessons Learned: CompletableFuture Security and Kafka Topic Grouping in Microservices

Issue 1: CompletableFuture + Missing Security Context = 401 Unauthorized

When we started using CompletableFuture.supplyAsync() in our Spring Boot microservice, some calls to other services (via Feign client) started failing with 401 Unauthorized.

The reason:

  • CompletableFuture runs in a separate thread.
  • By default, the Spring Security context (and JWT token) is not propagated to that new thread.
  • As a result, our Feign interceptor couldn’t attach the Authorization header, and the downstream service rejected the request.

Fix: We wrapped our executor with DelegatingSecurityContextExecutorService so that the SecurityContext (including the JWT token) travels along with async tasks. After this change, the token was correctly added and the 401s disappeared.


Issue 2: Kafka Consumers and Group IDs

We also ran into a Kafka consumer issue. Initially, we used the same consumer group ID for multiple topics. This caused unexpected behavior:

  • Consumers in the same group share messages.
  • With a single group ID, messages from different topics were getting “competed” for by the same group, leading to missed or unbalanced consumption.

Fix: We gave each topic its own unique group ID. This way, each topic is consumed independently, and no messages are skipped.


Takeaway:

  • For async code in Spring Security, always make sure the security context is propagated.
  • For Kafka, think carefully about group IDs — same group = load balancing, different groups = independent consumption.

Top comments (0)