w3c tracestate header not propagated
See original GitHub issueDescribe the bug
Using:
- spring-boot-starter-parent 2.4.4
- spring-cloud-dependencies 2020.0.3
- spring-cloud-sleuth: 3.0.3
- spring-cloud-starter-openfeign: 3.0.3
I have a simple RestController in service A that receives a POST request containing traceparent as well as tracestate header. The RestController calls another service B via a FeignClient. The traceparent header gets propagated correctly from service A to B. However, tracestate header is not propagated from service A to B.
According to w3c standard (https://www.w3.org/TR/trace-context/#mutating-the-tracestate-field) the tracestate header should be propagated (“Vendors receiving a tracestate request header MUST send it to outgoing requests. It MAY mutate the value of this header before passing to outgoing requests.”)
Sample
Reproduce with:
curl -X POST -H "Content-Type: application/json" -H "traceparent: 00-8df82d9e560f4c318f2c3c1ce7d69a0a-8dc0d640e5c62ebe-01" -H "tracestate: sappp=CwAAmEnGj0gThK52TCXZ270X8nBhc3Nwb3J0LWFwcABQT1NU" localhost:8003/notify
pom.xml (parent)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath />
</parent>
<groupId>com.bugtracking.sample</groupId>
<artifactId>tracestate</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>Parent POM</name>
<description>The parent POM
</description>
<properties>
<revision>0.0.1-SNAPSHOT</revision>
<java.version>11</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
<zipkin-version>2.2.8.RELEASE</zipkin-version>
<hystrix-version>2.2.8.RELEASE</hystrix-version>
</properties>
<modules>
<module>service-a</module>
<module>service-b</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Service A
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bugtracking.sample</groupId>
<artifactId>tracestate</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>service-a</artifactId>
<name>service-a</name>
<description>A Spring Boot sample</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
<version>${zipkin-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
Application.java
@EnableFeignClients
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
BClient.java
@FeignClient(name = "feign-client", url = "http://localhost:8001")
public interface BClient {
@PostMapping(path = "/serviceb", produces = "application/json", consumes = "application/json")
void outgoingRequest();
}
WebController.java
@RestController
public class WebController {
private final BClient feignClient;
@Autowired
public WebController(BClient feignClient) {
this.feignClient = feignClient;
}
@PostMapping(value = "/notify", consumes = MediaType.APPLICATION_JSON_VALUE)
public void notifyAllocation() {
feignClient.outgoingRequest();
}
}
application.yaml
server.port: 8003
# Actuator Endpoint Configurations
info: # /actuator/info
app:
name: ${spring.application.name}
management:
endpoints:
web:
exposure:
include:
- "*"
spring:
application:
name: service a
#zipkin:
# baseUrl: http://localhost:9411
sleuth:
sampler:
probability: 1.0
spring.sleuth.propagation.type: W3C
Service B
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bugtracking.sample</groupId>
<artifactId>tracestate</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>service-b</artifactId>
<name>service-b</name>
<description>A Spring Boot sample</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
Application.java
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
WebController.java
@RestController
public class WebController {
private static final Logger LOGGER = LoggerFactory.getLogger(WebController.class);
@PostMapping(value = "/serviceb", consumes = MediaType.APPLICATION_JSON_VALUE)
public void preference(@RequestHeader("traceparent") String traceparent, @RequestHeader("tracestate") String tracestate) {
LOGGER.info("traceparent: {}", traceparent);
LOGGER.info("tracestate: {}", tracestate);
}
}
application.yaml
server.port: 8001
# Actuator Endpoint Configurations
info: # /actuator/info
app:
name: ${spring.application.name}
management:
endpoints:
web:
exposure:
include:
- "*"
spring:
application:
name: service b
sleuth:
sampler:
probability: 1.0
spring.sleuth.propagation.type: W3C
Result
2021-07-27 15:01:57.471 WARN 34296 --- [nio-8001-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingRequestHeaderException: Missing request header 'tracestate' for method parameter of type String] in Service B
Issue Analytics
- State:
- Created 2 years ago
- Comments:11 (7 by maintainers)

Top Related StackOverflow Question
Tried this. tracestate header still missing.
Yeah and the same on the extractor. Let me see what I can do about this.