-
Notifications
You must be signed in to change notification settings - Fork 321
Description
Tracer Version(s)
1.57.0, 1.56.3, 1.51.1
Java Version(s)
25.0.0, 21.0.1
JVM Vendor
Amazon Corretto
Bug Report
Overview of the problem
NoSuchFieldError exceptions occur on a Java record type when the Datadog Java tracer is attached with integrations enabled. The failures occur in a JVM‑based HTTP service where a record is constructed via a static parse factory method from HTTP query parameters.
The same binary, under the same test load, behaves correctly when:
- The Datadog Java tracer is disabled, or
- The tracer is enabled but all integrations are disabled via
-Ddd.integrations.enabled=false, or - The problematic
recordis refactored into a plain Java class.
The NoSuchFieldError complains about fields or static constants that are clearly present in the compiled record class (verified via decompilation), and it only manifests when the Datadog Java tracer integrations are active. This strongly suggests an issue with bytecode instrumentation of Java records rather than a pure application or JVM bug.
Environment
Runtime / OS
-
Java versions:
- Java 21 (LTS)
- Java 25 (early LTS)
The issue has been observed under both versions in CI deployments.
-
OS / architecture:
- Linux,
aarch64(Arm64), running on cloud provider Arm‑based instances.
- Linux,
Datadog Java tracer versions
We have observed the issue with all of the following versions in production‑like CI environments:
- 1.51.1
- 1.56.3
- 1.57.0
Across these versions, the behavior is consistent:
- With integrations enabled, the
recordultimately fails withNoSuchFieldError. - With integrations globally disabled (
-Ddd.integrations.enabled=false), the same scenario passes consistently.
Failure does not occur for every HTTP request that references the record class, but occurs for a majority of such requests (at least 75% of observed cases).
Observed behavior details
When the Datadog Java tracer is attached with integrations enabled on Linux aarch64 and Java 21 or 25, the service occasionally fails requests that exercise this record type with java.lang.NoSuchFieldError.
The errors report that:
- A static
Patternfield on the record is missing, and/or - The record's canonical field (such as
snackType) is missing.
These failures occur even though the compiled class file clearly defines these fields and the same binary passes unit tests and local runs.
The behavior is intermittent and tied to the presence of the tracer and its integrations:
- The same request sometimes returns HTTP 200 and sometimes fails with
NoSuchFieldErroron the same process and deployment. - Disabling all agents (eg. Datadog and JaCoCo) eliminates the failures.
- Disabling other agents while leaving Datadog enabled, does not eliminate the failures.
- Disabling Datadog integrations globally with
-Ddd.integrations.enabled=falseeliminates the failures, even though the tracer remains attached. - Converting the record to a regular class eliminates the failures regardless of Datadog and integrations enabled.
What we tested (matrix-style summary)
- ❌ Record + Datadog tracer + integrations ON → intermittent
NoSuchFieldError. - ❌ Record + Datadog tracer ON + JaCoCo and other agents OFF →
NoSuchFieldErrorpersists. - ✅ Record + Datadog tracer +
-Ddd.integrations.enabled=false→NoSuchFieldErrornever observed. - ✅ Record + Datadog tracer +
-Ddd.integrations.enabled=false+ full integration list below enabled →NoSuchFieldErrornever observed. - ❌ Record + Datadog tracer +
-Ddd.integrations.enabled=true+ full integration list below disabled →NoSuchFieldErrorpersists. - ✅ Class (instead of
record) + Datadog tracer + integrations ON →NoSuchFieldErrornever observed.
Full integrations list reference
## Low risk category
-Ddd.integration.aws-sdk.enabled=true
-Ddd.integration.couchbase.enabled=true
-Ddd.integration.httpurlconnection.enabled=true
-Ddd.integration.httpclient.enabled=true
-Ddd.integration.apache-httpclient.enabled=true
-Ddd.integration.apache-http-client.enabled=true
## Highly scrutinized category
-Ddd.integration.jetty.enabled=true
-Ddd.integration.jax-rs.enabled=true
-Ddd.integration.jaxrs.enabled=true
-Ddd.integration.jax-rs-annotations.enabled=true
-Ddd.integration.jax-rs-filter.enabled=true
-Ddd.integration.servlet.enabled=true
-Ddd.integration.servlet-2.enabled=true
-Ddd.integration.servlet-3.enabled=true
Questions for maintainers
- Are there any known issues with Datadog Java tracer instrumentation of Java records (especially on Linux
aarch64and recent Java versions) that could produceNoSuchFieldErroronrecordfields or static constants? - Are there other specific integrations you would recommend disabling individually (via
-Ddd.integration.<name>.enabled=false) that are known to rewrite application classes in ways that might affect records? - Can you offer further advice and guidance to troubleshoot this issue?
Expected Behavior
With the Datadog Java tracer attached and integrations enabled:
- Java record classes should behave identically to their compiled bytecode.
- Static fields and canonical record fields should remain present and accessible at runtime.
- Enabling integrations should not introduce
NoSuchFieldErroron legitimate fields, regardless of concurrency or load.
Reproduction Code
At a high level, the problematic pattern looks like this in terms of structure:
public enum SnackType {
PIZZA,
// ...
}
public record MySnackFilter(SnackType snackType) {
private static final Pattern MATCH_THINGS = Pattern.compile("\"(.*)\"");
public static MySnackFilter parse(String filterExpression) {
// Parses a filter expression and resolves snack type details
return new MySnackFilter(resolvedSnackType);
}
}The record is used in an HTTP handler that runs on every request to parse a query parameter and construct a MySnackFilter instance. When the bug manifests, we see NoSuchFieldError reported for:
- The static
Patternfield (for example,MATCH_THINGS). - The canonical
recordfield (for example,snackType).
The same class, when converted to an ordinary Java class with equivalent fields and logic, does not reproduce under the same Datadog configuration and test load.
Steps to reproduce
-
Implement a small HTTP endpoint (JAX-RS, eg Jersey) that:
- Accepts a GET request with a query parameter such as
filter=snackType eq "PIZZA"(orfilter=snackType+eq+%27PIZZA%27). - Uses a Java
recordsimilar toMySnackFilterwith a staticparse(String filter)method that:- Resolves an
enumvalue. - Optionally uses a static
Patternfield to match filter statements. This step is optional because we can reproduce with thePatternfield removed. - Constructs and returns a
recordinstance.
- Resolves an
- Accepts a GET request with a query parameter such as
-
Deploy this service on Linux
aarch64with Java 21 or Java 25. Attach the Datadog Java tracer using one of the versions listed in the Environment section, with integrations enabled. -
Drive concurrent traffic through the endpoint using an integration test suite or a load tool (for example repeated HTTP calls with curl, gatling, k6, Karate, etc).
-
Under these conditions, observe that:
- Some requests succeed with HTTP 200 and correctly construct the
record. - Some requests, on the same host, same container image, and same process, fail with HTTP 500 and a
java.lang.NoSuchFieldError, declaring therecord"does not have member field" for either:- The static
Patternfield, or - The record's canonical field (for example,
snackType).
- The static
- Some requests succeed with HTTP 200 and correctly construct the
-
Restart the service with the same Datadog Java tracer version but with
-Ddd.integrations.enabled=false, and re-run the same tests. Under this configuration,NoSuchFieldErrornever occurs; all tests and manual calls succeed. -
Change the
recordinto a plain Java class with equivalent fields and a similar static factory method, then re-enable Datadog integrations. Under the same CI tests and load,NoSuchFieldErrornever occurs; all tests and manual calls succeed.