From 876a5a17c358f8def1d32231463042eccb6d2e37 Mon Sep 17 00:00:00 2001 From: saravadeo Date: Sat, 18 Apr 2026 09:49:50 +0530 Subject: [PATCH] Include 5xx responses in default HTTP client error statuses Default client error range was 4xx only, so downstream HTTP spans did not mark 5xx responses as errors. Align defaults with server-side semantics by treating 500-599 as errors unless overridden. Fixes DataDog/dd-trace-java#10245 --- .../instrumentation/decorator/HttpClientDecoratorTest.groovy | 5 ++--- .../datadog/trace/agent/test/base/HttpClientTest.groovy | 2 +- .../src/bootTest/groovy/SpringWebfluxTest.groovy | 4 ++-- .../src/bootTest/groovy/SpringWebfluxTest.groovy | 4 ++-- .../src/main/java/datadog/trace/api/ConfigDefaults.java | 2 +- .../test/groovy/datadog/trace/api/ConfigCollectorTest.groovy | 2 +- .../src/test/groovy/datadog/trace/api/ConfigTest.groovy | 2 +- metadata/supported-configurations.json | 4 ++-- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpClientDecoratorTest.groovy b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpClientDecoratorTest.groovy index 1bc83457bd0..5c63520a2a2 100644 --- a/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpClientDecoratorTest.groovy +++ b/dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/HttpClientDecoratorTest.groovy @@ -200,9 +200,8 @@ class HttpClientDecoratorTest extends ClientDecoratorTest { 399 | [status: 399] | false 400 | [status: 400] | true 499 | [status: 499] | true - 500 | [status: 500] | false - 500 | [status: 500] | false - 500 | [status: 500] | false + 500 | [status: 500] | true + 599 | [status: 599] | true 600 | [status: 600] | false null | [status: null] | false null | null | false diff --git a/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy b/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy index e787feeda1f..33969d3f9b7 100644 --- a/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy +++ b/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy @@ -369,7 +369,7 @@ abstract class HttpClientTest extends VersionedNamingTestBase { trace(size(2)) { sortSpansByStart() basicSpan(it, "parent") - clientSpan(it, span(0), method, false, false, uri, 500, false) // not an error. + clientSpan(it, span(0), method, false, false, uri, 500, true) } server.distributedRequestTrace(it, trace(0).last()) } diff --git a/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-5.0/src/bootTest/groovy/SpringWebfluxTest.groovy b/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-5.0/src/bootTest/groovy/SpringWebfluxTest.groovy index 9b2cce333f2..97ee99313a9 100644 --- a/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-5.0/src/bootTest/groovy/SpringWebfluxTest.groovy +++ b/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-5.0/src/bootTest/groovy/SpringWebfluxTest.groovy @@ -416,8 +416,8 @@ class SpringWebfluxTest extends InstrumentationSpecification { sortSpansByStart() def traceParent trace(2) { - clientSpan(it, null, "http.request", "spring-webflux-client", "GET", URI.create(url), 500) - traceParent = clientSpan(it, span(0), "netty.client.request", "netty-client", "GET", URI.create(url), 500) + clientSpan(it, null, "http.request", "spring-webflux-client", "GET", URI.create(url), 500, true) + traceParent = clientSpan(it, span(0), "netty.client.request", "netty-client", "GET", URI.create(url), 500, true) } trace(2) { span { diff --git a/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-6.0/src/bootTest/groovy/SpringWebfluxTest.groovy b/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-6.0/src/bootTest/groovy/SpringWebfluxTest.groovy index f8ee39eabc8..2875fd96afe 100644 --- a/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-6.0/src/bootTest/groovy/SpringWebfluxTest.groovy +++ b/dd-java-agent/instrumentation/spring/spring-webflux/spring-webflux-6.0/src/bootTest/groovy/SpringWebfluxTest.groovy @@ -414,8 +414,8 @@ class SpringWebfluxHttp11Test extends InstrumentationSpecification { sortSpansByStart() def traceParent trace(2) { - clientSpan(it, null, "http.request", "spring-webflux-client", "GET", URI.create(url), 500) - traceParent = clientSpan(it, span(0), "netty.client.request", "netty-client", "GET", URI.create(url), 500) + clientSpan(it, null, "http.request", "spring-webflux-client", "GET", URI.create(url), 500, true) + traceParent = clientSpan(it, span(0), "netty.client.request", "netty-client", "GET", URI.create(url), 500, true) } trace(2) { span { diff --git a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java index 6fa778e74d3..f48a376db73 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java @@ -25,7 +25,7 @@ public final class ConfigDefaults { DEFAULT_HTTP_SERVER_ERROR_STATUSES = new BitSet(); DEFAULT_HTTP_SERVER_ERROR_STATUSES.set(500, 600); DEFAULT_HTTP_CLIENT_ERROR_STATUSES = new BitSet(); - DEFAULT_HTTP_CLIENT_ERROR_STATUSES.set(400, 500); + DEFAULT_HTTP_CLIENT_ERROR_STATUSES.set(400, 600); DEFAULT_GRPC_SERVER_ERROR_STATUSES = new BitSet(); DEFAULT_GRPC_SERVER_ERROR_STATUSES.set(2, 17); DEFAULT_GRPC_CLIENT_ERROR_STATUSES = new BitSet(); diff --git a/internal-api/src/test/groovy/datadog/trace/api/ConfigCollectorTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/ConfigCollectorTest.groovy index 7ac922c028c..ed6046563ba 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/ConfigCollectorTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/ConfigCollectorTest.groovy @@ -117,7 +117,7 @@ class ConfigCollectorTest extends DDSpecification { GeneralConfig.TELEMETRY_HEARTBEAT_INTERVAL | new Float(DEFAULT_TELEMETRY_HEARTBEAT_INTERVAL).toString() CiVisibilityConfig.CIVISIBILITY_GRADLE_SOURCE_SETS | "main,test" IastConfig.IAST_WEAK_HASH_ALGORITHMS | DEFAULT_IAST_WEAK_HASH_ALGORITHMS.join(",") - TracerConfig.TRACE_HTTP_CLIENT_ERROR_STATUSES | "400-500" + TracerConfig.TRACE_HTTP_CLIENT_ERROR_STATUSES | "400-600" } def "default null config settings are also collected"() { diff --git a/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy index faa4d04311e..8707d99098d 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy @@ -1122,7 +1122,7 @@ class ConfigTest extends DDSpecification { config.requestHeaderTags == [:] config.baggageMapping == [:] config.httpServerErrorStatuses == toBitSet((500..599)) - config.httpClientErrorStatuses == toBitSet((400..499)) + config.httpClientErrorStatuses == toBitSet((400..599)) config.httpClientSplitByDomain == false config.dbClientSplitByInstance == false config.dbClientSplitByInstanceTypeSuffix == false diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index ac7935039e3..f46b3dd4a85 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -1613,7 +1613,7 @@ { "version": "A", "type": "string", - "default": "400-499", + "default": "400-600", "aliases": [] } ], @@ -6261,7 +6261,7 @@ { "version": "A", "type": "string", - "default": "400-499", + "default": "400-600", "aliases": ["DD_HTTP_CLIENT_ERROR_STATUSES"] } ],