Since Spring Boot 3.1.4 I am getting an error during a test calling an actuator endpoint. I managed to create a minimal example that reproduces the issue, available here. The project contains a test that fails using 3.1.4, but succeeds with 3.1.3.

The project is a simple reactive application with Spring Security and tracing using brave.

I found key to reproducing the issue was: * @AutoConfigureObservability must be present. * management.tracing.baggage.correlation.fields must be set. * Hooks.enableAutomaticContextPropagation() must be present. * A custom SecurityWebFilterChain configuration is not necessarily required, it causes the call to the actuator endpoint to fail in a 500 internal server error. Without the custom security config, the error is still logged but not returned to the caller.

The stacktrace I am seeing:

2023-09-26T12:55:14.508+02:00 ERROR 84257 --- [     parallel-1] a.w.r.e.AbstractErrorWebExceptionHandler : [c9889f]  500 Server Error for HTTP GET "/actuator/health"

java.lang.AssertionError: Misalignment: popped updateScope false !=  expected false
    at brave.baggage.CorrelationFlushScope.popCurrentUpdateScope(CorrelationFlushScope.java:86) ~[brave-5.15.1.jar:na]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ org.springframework.web.filter.reactive.ServerHttpObservationFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ HTTP GET "/actuator/health" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at brave.baggage.CorrelationFlushScope.popCurrentUpdateScope(CorrelationFlushScope.java:86) ~[brave-5.15.1.jar:na]
        at brave.baggage.CorrelationFlushScope.close(CorrelationFlushScope.java:37) ~[brave-5.15.1.jar:na]
        at io.micrometer.tracing.brave.bridge.BraveScope.close(BraveCurrentTraceContext.java:114) ~[micrometer-tracing-bridge-brave-1.1.5.jar:1.1.5]
        at io.micrometer.tracing.handler.RevertingScope.close(RevertingScope.java:45) ~[micrometer-tracing-1.1.5.jar:1.1.5]
        at io.micrometer.tracing.handler.TracingObservationHandler.onScopeClosed(TracingObservationHandler.java:141) ~[micrometer-tracing-1.1.5.jar:1.1.5]
        at io.micrometer.observation.ObservationHandler$FirstMatchingCompositeObservationHandler.onScopeClosed(ObservationHandler.java:181) ~[micrometer-observation-1.11.4.jar:1.11.4]
        at io.micrometer.observation.SimpleObservation.notifyOnScopeClosed(SimpleObservation.java:254) ~[micrometer-observation-1.11.4.jar:1.11.4]
        at io.micrometer.observation.SimpleObservation$SimpleScope.close(SimpleObservation.java:318) ~[micrometer-observation-1.11.4.jar:1.11.4]
        at io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor.closeCurrentScope(ObservationThreadLocalAccessor.java:142) ~[micrometer-observation-1.11.4.jar:1.11.4]
        at io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor.restore(ObservationThreadLocalAccessor.java:148) ~[micrometer-observation-1.11.4.jar:1.11.4]
        at io.micrometer.context.DefaultContextSnapshot$DefaultScope.resetThreadLocalValue(DefaultContextSnapshot.java:152) ~[context-propagation-1.0.5.jar:1.0.5]
        at io.micrometer.context.DefaultContextSnapshot$DefaultScope.close(DefaultContextSnapshot.java:141) ~[context-propagation-1.0.5.jar:1.0.5]
        at reactor.core.publisher.MonoContextWriteRestoringThreadLocals.subscribe(MonoContextWriteRestoringThreadLocals.java:45) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribeWith(Mono.java:4561) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4462) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4398) ~[reactor-core-3.5.10.jar:3.5.10]
        at org.springframework.test.web.reactive.server.HttpHandlerConnector.lambda$doConnect$2(HttpHandlerConnector.java:100) ~[spring-test-6.0.12.jar:6.0.12]
        at org.springframework.mock.http.client.reactive.MockClientHttpRequest.lambda$writeWith$2(MockClientHttpRequest.java:124) ~[spring-test-6.0.12.jar:6.0.12]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:45) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.FluxConcatIterable$ConcatIterableSubscriber.onComplete(FluxConcatIterable.java:147) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.FluxConcatIterable.subscribe(FluxConcatIterable.java:60) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribeWith(Mono.java:4561) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4462) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4398) ~[reactor-core-3.5.10.jar:3.5.10]
        at org.springframework.test.web.reactive.server.HttpHandlerConnector.doConnect(HttpHandlerConnector.java:114) ~[spring-test-6.0.12.jar:6.0.12]
        at org.springframework.test.web.reactive.server.HttpHandlerConnector.lambda$connect$0(HttpHandlerConnector.java:81) ~[spring-test-6.0.12.jar:6.0.12]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:45) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:126) ~[reactor-core-3.5.10.jar:3.5.10]
        at io.micrometer.context.ContextSnapshot.lambda$wrap$0(ContextSnapshot.java:91) ~[context-propagation-1.0.5.jar:1.0.5]
        at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) ~[reactor-core-3.5.10.jar:3.5.10]
        at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) ~[reactor-core-3.5.10.jar:3.5.10]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Comment From: wilkinsona

Thanks for the sample. The problem does not occur with the recently released Micrometer Tracing 1.1.6. Next week's Spring Boot 3.1.5 release will use Micrometer Tracing 1.1.6 by default.