All Products
Search
Document Center

Managed Service for OpenTelemetry:Return a trace ID in an HTTP response header for Java and Node.js applications

Last Updated:May 27, 2026

By default, OpenTelemetry writes the trace ID only to request headers. Use a Java agent extension or a Node.js responseHook to include it in response headers.

Java applications

By default, the trace ID appears only in HTTP request headers. To include it in response headers, add an OpenTelemetry Java agent extension.

Choose one of the following methods:

  • Method 1: Use the pre-built extension from Managed Service for OpenTelemetry to add trace IDs to response headers.

  • Method 2: Build a custom extension. If the pre-built extension from Managed Service for OpenTelemetry does not meet your requirements, create your own Java agent extension and package it as a JAR file.

Method 1: Use the pre-built extension

Download the extension: ot-java-agent-extension-1.28.0.jar.

Managed Service for OpenTelemetry provides this extension. To return a trace ID and span ID in response headers, add the JAR file path to your startup parameters.

Modify startup parameters

Add the otel.javaagent.extensions parameter to your startup command: -Dotel.javaagent.extensions=/path/to/opentelemetry-java-agent-extension.jar

Complete startup command example:

java -javaagent:path/to/opentelemetry-javaagent.jar \
 -Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \
 -Dotel.exporter.otlp.headers=Authentication=<token> \
 -Dotel.exporter.otlp.endpoint=<endpoint> \
 -Dotel.metrics.exporter=none \
 -jar your-app.jar

Method 2: Build a custom Java agent extension

Prerequisites

  • The OpenTelemetry Java agent is configured.

  • OpenTelemetry Java agent version 1.24.0 or later.

  1. Write the Java agent extension.

    1. Create a new project.

    2. Add the following dependencies to pom.xml.

      The opentelemetry-javaagent dependency version must match the Java agent version you use.

       <dependencies>
       <dependency>
       <groupId>com.google.auto.service</groupId>
       <artifactId>auto-service</artifactId>
       <version>1.1.1</version>
       </dependency>
      
       <dependency>
       <groupId>io.opentelemetry.javaagent</groupId>
       <artifactId>opentelemetry-javaagent</artifactId>
       <version>1.28.0</version>
       <scope>compile</scope>
       </dependency>
       </dependencies>

    3. Create an AgentHttpResponseCustomizer class that implements HttpServerResponseCustomizer.

      package org.example;
      
      import com.google.auto.service.AutoService;
      import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.trace.Span;
      import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.trace.SpanContext;
      import io.opentelemetry.javaagent.shaded.io.opentelemetry.context.Context;
      import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer;
      import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator;
      
      @AutoService(HttpServerResponseCustomizer.class)
      public class AgentHttpResponseCustomizer implements HttpServerResponseCustomizer {
       @Override
       public <RESPONSE> void customize(Context context, RESPONSE response, HttpServerResponseMutator<RESPONSE> responseMutator) {
       SpanContext spanContext = Span.fromContext(context).getSpanContext();
       String traceId = spanContext.getTraceId();
       String spanId = spanContext.getSpanId();
      
       // Add the trace ID and the span ID to the HTTP response header. You can change the field name of the header based on your requirements.
       responseMutator.appendHeader(response, "TraceId", traceId);
       responseMutator.appendHeader(response, "SpanId", spanId);
       }
      }
  2. Build the extension.

    Package the project into a JAR file. The output is stored in the target directory.

    mvn clean package
  3. Load the extension at application startup.

    Add the otel.javaagent.extensions parameter to your startup command: -Dotel.javaagent.extensions=/path/to/opentelemetry-java-agent-extension.jar

    Complete startup command example:

    java -javaagent:path/to/opentelemetry-javaagent.jar \
     -Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \
     -Dotel.exporter.otlp.headers=Authentication=<token> \
     -Dotel.exporter.otlp.endpoint=<endpoint> \
     -Dotel.metrics.exporter=none \
     -jar yourapp.jar

Node.js applications

  1. (Optional) Run the node.js-demo project to integrate your Node.js application with OpenTelemetry.

    Skip this step if your application is already integrated with OpenTelemetry.

  2. Add a responseHook to the HTTP instrumentation.

    Use the responseHook parameter in HttpInstrumentationConfig to inject custom headers into responses before they are sent. The following example adds a trace ID and span ID to the response header.

    ...
    
    // The content to be replaced.
    // registerInstrumentations({
    // tracerProvider: provider,
    // instrumentations: [new HttpInstrumentation(), ExpressInstrumentation],
    // });
    
    
    
    
    const httpInstrumentation = new HttpInstrumentation({
     // Add a custom response hook.
     responseHook: (span, response) => {
    
     // Obtain the trace ID and the span ID from the context.
     const traceId = span.spanContext().traceId;
     const spanId = span.spanContext().spanId;
    
     // Add the trace ID and the span ID to the HTTP response header.
     response.setHeader('TraceId', traceId);
     response.setHeader('SpanId', spanId);
     // Return the response object.
     return response;
     },
    });
    
    
    registerInstrumentations({
     tracerProvider: provider,
     instrumentations: [httpInstrumentation, ExpressInstrumentation],
    });
    
    ...