This release targets the OpenTelemetry SDK 1.61.0.
Note that many artifacts have the -alpha suffix attached to their version number, reflecting that they will continue to have breaking changes. Please see VERSIONING.md for more details.
⚠️ Breaking changes to non-stable APIs
- Make
AbstractKtorServerTelemetryBuilder.isOpenTelemetryInitialized()protected (previously public). (#17509) - Replace
ExperimentalInstrumentationModule.injectClasses(ClassInjector)withexposedClassNames()for exposing helper classes to the application class loader. (#17765) - Moved
WebApplicationContextInstrumentationfrom thespring-webinstrumentation module tospring-webmvc; users who disabled it viaotel.instrumentation.spring-web.enabled=falsemust now useotel.instrumentation.spring-webmvc.enabled=false. (#17856)
🚫 Deprecations
- Deprecated
KafkaTelemetryBuilder.setMessagingReceiveInstrumentationEnabled(boolean)in favor ofsetMessagingReceiveTelemetryEnabled(boolean). (#17092) - Deprecated GraphQL builder methods
setSanitizeQuery()andsetAddOperationNameToSpanName(), and deprecated config keyotel.instrumentation.graphql.add-operation-name-to-span-name.enabledin favor ofsetQuerySanitizationEnabled(),setOperationNameInSpanNameEnabled(), andotel.instrumentation.graphql.operation-name-in-span-name.enabled. (#17093) - Deprecate
Experimental.setEnableSqlCommenter()in JDBC and R2DBC instrumentation in favor ofExperimental.setSqlCommenterEnabled(). (#17094) - Rename
otel.instrumentation.servlet.capture-request-parameterstootel.instrumentation.servlet.experimental.capture-request-parametersandotel.instrumentation.servlet.add-trace-id-request-attributetootel.instrumentation.servlet.experimental.trace-id-request-attribute.enabled; old property names are deprecated. (#17113) - Deprecated the declarative config name
statement_sanitizerin favor ofquery_sanitization, and the declarative config groupcommon.databasein favor ofcommon.db. (#17116) - Deprecated the GraphQL declarative config name
query_sanitizerin favor ofquery_sanitization. (#17455) - Deprecated the DB query sanitization system property names
otel.instrumentation.common.db-statement-sanitizer.enabled,otel.instrumentation.jdbc.statement-sanitizer.enabled,otel.instrumentation.mongo.statement-sanitizer.enabled, andotel.instrumentation.r2dbc.statement-sanitizer.enabledin favor of the corresponding*.query-sanitization.enablednames, deprecatedotel.instrumentation.common.experimental.db-sqlcommenter.enabledin favor ofotel.instrumentation.common.db.experimental.sqlcommenter.enabled, and deprecatedotel.instrumentation.graphql.query-sanitizer.enabledin favor ofotel.instrumentation.graphql.query-sanitization.enabled. (#17464) - Deprecate
InstrumentationModule.isIndyModule(); indy mode is now determined by the agent distribution configuration instead of per-module overrides. (#17713)
📈 Enhancements
- Remove
log4j.map_message.prefix from MapMessage attributes whenotel.instrumentation.common.v3-previewis enabled. (#13871) - Stop normalizing messaging header names (dash to underscore) when
otel.instrumentation.common.v3-previewis enabled, so captured header attribute keys now preserve the original header name. (#14554) - Add
db.system.nameattribute to Vertx SQL client instrumentation when stable database semantic conventions are enabled (otel.semconv-stability.opt-in=database). (#16254) - JDBC instrumentation now supports the
db.system.nameattribute with stable semantic convention values (e.g.,postgresql,oracle.db,ibm.db2,sap.hana) when stable database semantic conventions are enabled (otel.semconv-stability.opt-in=database). (#16277) - Add
otel.instrumentation.common.v3-previewflag that enables upcoming 3.0 breaking changes early. (#16459) - Optimized log event MDC attribute mapping in jboss-logmanager, log4j, and logback appenders by pre-computing attribute keys at initialization. (#16765)
- Add
messaging.kafka.bootstrap.serversattribute to Kafka producer spans whenotel.instrumentation.kafka.experimental-span-attributesis enabled. (#17065) - Disable servlet trace-id request attribute by default when
otel.instrumentation.common.v3-previewis enabled. (#17173) - Disable thread details span processor (
otel.javaagent.add-thread-details) by default whenotel.instrumentation.common.v3-previewis enabled. (#17215) - Improved javaagent startup optimization by decomposing disjunction matchers, allowing more transformations to be skipped during class loading. (#17227)
- Add stable
messaging.kafka.offsetattribute to Kafka instrumentation, gated behindotel.semconv-stability.preview=messaging. (#17785) - Preserve original casing of servlet request parameter names in attribute keys when
otel.instrumentation.common.v3-previewis enabled. (#17822) - Replace reflective mutation of Byte Buddy's
AgentBuilder.Default.transformationswith aClassFileTransformerhook, avoiding a JDK 26 JEP 500 warning about writing to a final field via reflection. (#17824) - Add javaagent bridging support for OpenTelemetry API 1.61 stable methods including
Tracer.isEnabled(), metric instrumentisEnabled(), andLogger.setBody(Body). (#17849)
🛠️ Bug fixes
- Fix
WebClientBeanPostProcessorandRestClientBeanPostProcessorto avoid replacing user-customized builder beans when the OpenTelemetry tracing filter/interceptor is already registered. (#15546) - Fix memory leak where bridged observable metric callbacks were never closed when the application-side instrument was garbage collected. (#16219)
- Fix Ktor server instrumentation leaking scope across requests due to
restoreThreadContextnot always being called by Ktor coroutine machinery. (#16487) - Add missing
schemaUrlto servlet response instrumenter. (#16560) - Fix
OpenTelemetryContextDataProvidercallingGlobalOpenTelemetry.get()during class initialization, which could interfere with SDK setup ordering. (#16638) - Fix ZIO instrumentation destroying caller thread context on fiber suspend, which caused spans created after
unsafe.runto lose their parent. (#16647) - Fix Spring Boot starter adding a duplicate OpenTelemetry logback appender when the appender is nested inside another appender. (#16697)
- Fix bridging of
VALUE-type attributes set viaAttributeKey.valueKey()on spans and log records through the javaagent API bridge. (#16750) - Fix unsafe deserialization in RMI instrumentation that could lead to remote code execution (CVE-2026-33701, #16986, also released in 2.26.1)
- Fix boot loader class injection for
httpurlconnection,methods, andrmiinstrumentations to useMethodHandles.Lookupinstead of unsafe fallback on JDK 23+. (#17050) - Fix runtime-telemetry to fall back to JMX metrics when
preferJfris enabled but JFR is not available. (#17058) - Fix
NullPointerExceptionin servlet instrumentation when response object is null during error handling. (#17087) - Limit sanitized Redis command length to 32 KB to prevent excessive memory usage from very large commands. (#17139)
- Fix Apache Dubbo 2.7 instrumentation SPI resource path so that filters are properly discovered by Dubbo's extension loader. (#17210)
- Log suppressed failures from Netty HTTP server response customization instead of swallowing them. (#17220)
- Fix span leak on cancelled requests in Spring WebFlux server library instrumentation. (#17222)
- Fix Kafka wrapped producer to respect
setPropagationEnabled(false)and not inject trace context into message headers when propagation is disabled. (#17231) - Fix deadlock in
IgnoredClassLoadersMatchercaused bycomputeIfAbsentholding a lock while callingloadClass. (#17241) - Fix Pulsar consumer instrumentation failing to instrument message listeners in newer Pulsar client versions where
triggerListenerwas refactored into a lambda. (#17405) - Fix Kafka producer wrapper silently dropping context propagation when
ProducerRecordheaders are read-only (e.g. when a record is sent a second time). (#17530) - Fix
NullPointerExceptionin Undertow instrumentation when the active-handlers context key is absent. (#17559) - Fix
HttpServerResponseCustomizererror isolation so that a failing customizer no longer prevents subsequent customizers from running. (#17617) - Fix
rocketmq-client-4.8instrumentation not recording spans for ONEWAY messages. (#17656) - Fix internal application logger not activating when
otel.instrumentation.common.default-enabledis set tofalse. (#17657) - Fix floating-point precision issue when converting Micrometer timer histogram bucket boundaries from nanoseconds to the target time unit. (#17715)
- Fix
ClassNotFoundExceptioninMicrometerBridgeAutoConfigurationwhen Spring Boot Actuator metrics module is not on the classpath in Spring Boot 4. (#17723) - Align RMI context propagation limits with Tomcat defaults, reducing max entries from 1000 to 100 and adding an 8 KB total size limit to prevent excessively large payloads. (#17870)
- Fix runtime-telemetry unconditionally enabling experimental JFR-based metrics when
otel.instrumentation.runtime-telemetry.emit-experimental-metrics=true, which could impose unwanted JFR recording overhead on users who only wanted the JMX-based experimental metrics. JFR-based experimental metrics are now gated by a separateotel.instrumentation.runtime-telemetry.emit-experimental-jfr-metricsproperty. (#18110)
🙇 Thank you
This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:
@breedx-splk
@caglareker
@divitsinghall
@IswaryaIyapalam
@jaydeluca
@kchrusciel
@kriegaex
@laurit
@lenin-jaganathan
@lmolkova
@lucacavenaghi97
@maryliag
@mznet
@onurkybsi
@pepeshore
@sam-ov
@steverao
@SylvainJuge
@trask
@Tusharika725
@unalpolat
@utafrali
@wpessers
@xiangtianyu
@YaoYingLong
@zeitlinger
@zhenlin-pay2