A new RestClient built outside the auto-configured builder can make an outgoing request appear as a new trace instead of a child span.
Spring Boot tracing across RestClient: construct the client from Boot's builder
Keep the trace chain
The parcel API calls the rate service after accepting a request. Spring Boot instruments clients created from its auto-configured RestClient.Builder; creating a separate RestClient from scratch can omit propagation interceptors. The downstream service then logs a different trace ID, making one operation look like two. Request-factory selection and timeouts still apply to the same client; tracing is not a replacement for a deadline.
Avoid trusting client-supplied trace claims
Trace headers help correlate work; they are not authentication or authorization data. A malicious caller can supply a trace ID, so keep tenant and identity checks in the security boundary. Do not place tokens or parcel addresses in span attributes. Instrument a stable operation name and bounded low-cardinality tags.
Follow one request
Call the parcel API, let it call the rate service, and compare trace IDs and parent-child spans in the collector. Repeat with the client created outside the managed builder to demonstrate the gap. This bean is only a client-construction sketch; tracing dependencies, exporter and sampling still need configuration.
Implementation sketch
@Bean
RestClient rateClient(RestClient.Builder builder) {
return builder.baseUrl("https://rate-service.internal")
.build();
}Cost and verification
Tracing adds context propagation and exporter traffic. A low sample rate reduces storage but can hide individual failures; use logs and metrics for unsampled requests.
Common Mistakes
- Do not construct a new unmanaged RestClient and assume Boot propagation follows it.
- Do not treat trace headers as an identity source.
- Do not put secrets or high-cardinality personal data into span tags.
Read next
Spring Boot observation context across @Async and Reactor handoffs, Spring async trace context: follow work across executor threads, Spring RestClient request factories: pin the transport you test, Spring Boot metrics: bound tag values instead of tracking each receipt.
