The OpenTelemetry Java agent 3.0 renames your metrics and ships GA this month
Version 2.32.0 of the OpenTelemetry Java agent, released on October 6, 2026, serves as the release candidate for 3.0, which is slated to go stable this month: attribute names, units, and trace shapes all change. Turn on dual emission with the /dup flag and compare your telemetry before the new schema becomes the default.
October 6, 2026. The OpenTelemetry Java agent team ships version 2.32.0. October 2026. Version 3.0 is announced for this same month. Two years. That is how long the current semantic conventions have lasted, and they are about to change all at once. Why it matters: the Java agent is the most widely deployed zero-code instrumentation in the Java world, and 3.0 renames attributes, changes units, and restructures traces — in other words, it can break your dashboards, alerts, and pipelines without touching a single line of your application.
What 3.0 changes, in one paragraph
OpenTelemetry has organized 3.0 around a simple principle: the semantic conventions finally become stable, and the agent applies the new defaults. Concretely, three domains move. The database and code conventions become stable defaults. The messaging conventions adopt a newer, still-experimental version. And some capture settings and instrumentation defaults change value. The blog post presenting the release candidate is unambiguous: “3.0 changes telemetry, configuration, and instrumentation defaults.”
The tricky part for a production team is that these are not cosmetic renames. They touch names, values, types, and units. Renaming a key is not enough: you must also verify that the value has not changed, and that a threshold expressed in milliseconds does not need to be converted to seconds.
Names that change, and units that change too
The clearest example comes from JDBC. A PostgreSQL connection to the orders database, configured on the public schema, today produces a span carrying db.system: "postgresql", db.name: "orders", and db.statement: "SELECT * FROM orders". Under 3.0, those attributes become db.system.name: "postgresql", db.namespace: "orders|public", and db.query.text: "SELECT * FROM orders". Note the trap: db.namespace merges database and schema into orders|public, while db.name only held orders. Check the values, not just the keys.
The list of changes is long, and a few are easy to miss:
db.client.connections.maxbecomesdb.client.connection.limit— swapping “connections” for “connection” is not enough;db.system: "mssql"becomesdb.system.name: "microsoft.sql_server";- database connection-pool duration metrics move from milliseconds to seconds;
code.namespaceandcode.functionmerge intocode.function.name;enduser.idbecomesuser.name, andenduser.role— a comma-separated string — becomesuser.roles, an array of strings;enduser.scope, meanwhile, disappears with no replacement.
Each of those points corresponds to a query in some dashboard or an alert condition somewhere. That is exactly why OpenTelemetry provides a bridge: dual emission.
Dual emission: test before you break
Version 2.32.0 introduces an explicit comparison mechanism. With the umbrella flag off and a /dup suffix, the agent emits the old and new schemas side by side, for the domains that support it:
OTEL_INSTRUMENTATION_COMMON_V3_PREVIEW=false \
OTEL_SEMCONV_STABILITY_OPT_IN=database/dup,code/dup \
OTEL_SEMCONV_STABILITY_PREVIEW=messaging/dup You capture a baseline first, then flip the umbrella flag to test the conventions and defaults together:
OTEL_INSTRUMENTATION_COMMON_V3_PREVIEW=true Two limits worth knowing. First, dual emission does not preserve every legacy instrument or both trace shapes. Connection-pool metrics switch to the new names and units even with /dup, and a span has only one name and one kind. Second, in preview mode the Zipkin exporter support is removed — you must switch to OTLP.
Messaging changes its trace shape
The trickiest domain is messaging, which moves from semantic conventions v1.24 to v1.43. For Kafka, span names change: orders publish becomes send orders, orders receive becomes poll orders, orders process becomes process orders. The operation now comes first and reflects the client API. The old messaging.operation attribute splits into messaging.operation.name and messaging.operation.type: for a Kafka poll, the name is poll and the type is receive.
What can genuinely surprise you are the parent relationships. Under the old schema, a process span could be a child of the producer’s send span. Under the new one, when processing runs inside an active application span (say, one created by @WithSpan), that span becomes the parent of the process span, and the process span only links the producer’s span. The result: traces that used to group together now split apart, and your per-service aggregations change shape. The poll span becomes an independent CLIENT span instead of a CONSUMER.
Metrics follow suit: messaging.publish.duration and messaging.receive.duration converge on messaging.client.operation.duration, and messaging.receive.messages becomes messaging.client.consumed.messages. Again, check values as well as names.
Capture settings and instrumentations move too
3.0 is not only renames: it can add or remove telemetry. If your application already attaches structured fields to its logs via SLF4J key-value pairs, those fields can show up in exported logs without enabling capture separately, once the umbrella flag is on. MDC capture stays separate and opt-in.
In the other direction, some instrumentations turn off by default: Hibernate, Hystrix, and Twilio. If you depend on them, you must re-enable them explicitly, or the corresponding spans silently vanish from your traces. That is the kind of silent regression dual emission will not necessarily surface, since it only compares what is emitted — not what stops being emitted.
For the migration itself, OpenTelemetry ships a toolbox. Declarative configuration (still experimental) lets you drive the agent from a YAML file via -Dotel.config.file=/path/to/otel-config.yaml, with a converter for existing configuration. The database semantic convention migration guide documents the mappings attribute by attribute. And the Ecosystem Explorer exposes versioned instrumentation metadata you can hand to an AI agent to draft dashboard and alert updates — asking it, as the blog post suggests, to flag every unproven mapping with VERIFY rather than assume.
There is a bigger story behind the churn. Semantic conventions are the shared vocabulary that makes telemetry from different languages and vendors comparable, and their database and code portions have spent years hovering between “experimental” and “stable”. 3.0 is the moment they get promoted — which is why the changes land all at once, and why the project built /dup dual emission rather than a silent switch. For teams that normalized on OpenTelemetry as their single source of truth, that is good news in the long run: the schema they are migrating to is the one that is supposed to stop moving. The practical upshot is a process, not a flag — capture a baseline, run /dup, reconcile, then flip the umbrella. Teams that do it while 3.0 is still a release candidate do it deliberately; teams that wait for GA inherit the same diffs without the preview window.
Verdict
The 3.0 of the OpenTelemetry Java agent is a real breaking change dressed as a minor update, and its date — this month — leaves you little room. If you run the Java agent in production, do not wait for GA: roll out 2.32.0 to a test environment now, capture a baseline, turn on /dup, and sweep your dashboards and alerts for the new names, values, and units. If you still export to Zipkin, plan the move to OTLP before anything else — support disappears in preview mode. And if you maintain a distribution or extension of the agent, test right away: invokedynamic instrumentation becomes the default, which changes how your helper classes load. Teams that switch now will do it at their own pace; those that wait for GA will do it under pressure, the day their alerts stop matching.