[BUG] azure-core-http-netty ignores response timeout when write timeout is disabled
メンテナーはふだん 1 日以内に返信
評価
この issue はまだ評価されていません。
説明
Describe the bug
With azure-core-http-netty 1.16.5, setting writeTimeout(Duration.ZERO) also prevents the configured response timeout from firing.
I reproduced this with a WireMock endpoint that matches the request body and delays its response by one second. With a 100 ms response timeout and write timeout disabled, the request succeeds after about one second. Setting a positive write timeout makes the same request time out after about 100 ms.
Disabling the write timeout should only disable the write timeout, not the response timeout.
Exception or Stack Trace
No SDK exception is thrown in the disabled-write case. The reproducing test fails with this assertion:
org.opentest4j.AssertionFailedError: Expected java.lang.RuntimeException to be thrown, but nothing was thrown.
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:73)
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:35)
at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3128)
at AzureNettyResponseTimeoutWireMockTest.responseTimeoutShouldNotDependOnWriteTimeout(AzureNettyResponseTimeoutWireMockTest.java:53)
To Reproduce
- In a Java test project using
azure-core-http-netty:1.16.5and JUnit Jupiter, add the WireMock test dependency below if it is not already available. - Copy the test class below into
src/test/java/AzureNettyResponseTimeoutWireMockTest.java. - Run
mvn -Dtest=AzureNettyResponseTimeoutWireMockTest test(from the HTTP Netty module if using the SDK repository). - Observe that the
writeTimeoutMillis=0case fails because no exception is thrown; thewriteTimeoutMillis=5000control case passes with the expected SDK response-timeout exception. No Azure credentials or service are required.
Verified output:
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0
Maven exits with code 1 because the disabled-write case reproduces the bug.
Code Snippet
WireMock test dependency, if needed. The standalone artifact avoids changing the project's Jetty dependencies:
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock-standalone</artifactId>
<version>3.13.1</version>
<scope>test</scope>
</dependency>
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpMethod;
import com.azure.core.http.HttpRequest;
import com.azure.core.http.HttpResponse;
import com.azure.core.http.netty.NettyAsyncHttpClientBuilder;
import com.github.tomakehurst.wiremock.WireMockServer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.time.Duration;
import java.util.concurrent.TimeoutException;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class AzureNettyResponseTimeoutWireMockTest {
private WireMockServer wireMock;
@BeforeEach
void setUp() {
wireMock = new WireMockServer(wireMockConfig().bindAddress("127.0.0.1").dynamicPort());
wireMock.start();
wireMock.stubFor(post(urlEqualTo("/timeout"))
.withRequestBody(equalTo("payload"))
.willReturn(aResponse().withStatus(200).withFixedDelay(1_000)));
}
@AfterEach
void tearDown() {
if (wireMock != null) wireMock.stop();
}
@ParameterizedTest(name = "writeTimeoutMillis={0}")
@ValueSource(longs = {0, 5_000})
@Timeout(10)
void responseTimeoutShouldNotDependOnWriteTimeout(long writeTimeoutMillis) {
HttpClient client = new NettyAsyncHttpClientBuilder()
.writeTimeout(Duration.ofMillis(writeTimeoutMillis))
.responseTimeout(Duration.ofMillis(100))
.build();
HttpRequest request = new HttpRequest(HttpMethod.POST, "http://127.0.0.1:" + wireMock.port() + "/timeout")
.setBody("payload");
RuntimeException failure = assertThrows(RuntimeException.class, () -> {
try (HttpResponse ignored = client.send(request).block(Duration.ofSeconds(3))) {
// Returning normally means the configured response timeout did not fire.
}
});
Throwable root = failure;
while (root.getCause() != null) root = root.getCause();
assertInstanceOf(TimeoutException.class, root);
assertTrue(root.getMessage().contains("Channel response timed out"));
}
}
Only writeTimeout and responseTimeout are configured on the SDK client; all other client settings retain their defaults. The three-second blocking timeout is just a test safety bound, and the assertion specifically checks the SDK's response-timeout exception.
Expected behavior
Both parameterized cases should pass: with a 100 ms response timeout and a one-second server response delay, the SDK should throw a response-timeout exception whether the write timeout is enabled or disabled.
Screenshots
Not applicable.
Setup (please complete the following information):
- OS: macOS 26.5
- IDE: Not applicable; reproduced from the terminal using Maven.
- Library/Libraries:
com.azure:azure-core-http-netty:1.16.5com.azure:azure-core:1.58.1(SDK transitive dependency)io.projectreactor.netty:reactor-netty-http:1.2.18(SDK transitive dependency)org.junit.jupiter:junit-jupiter:5.13.4(test dependency)org.wiremock:wiremock-standalone:3.13.1(test dependency)
- Java version: Temurin OpenJDK 26.0.1+8. The reproduction compiles with Java release 17.
- App Server/Environment: Standalone Maven/JUnit test with a local HTTP server on
127.0.0.1; no application server or Azure service. - Frameworks: JUnit Jupiter and WireMock. No Spring Boot or other application framework.
The standalone reproduction uses the SDK's normal transitive dependencies. No NoClassDefFoundError or NoSuchMethodError occurs in this reproduction; a dependency version mismatch is not suspected.
Additional context
The suspected cause is in Azure SDK's own AzureSdkHandler, rather than Netty or Reactor Netty:
sdk/core/azure-core-http-netty/src/main/java/com/azure/core/http/netty/implementation/AzureSdkHandler.java
Source, lines 129-138: the write-completion listener is installed only when writeTimeoutMillis > 0 at line 129. That listener also calls startResponseTracking() at line 134. When write timeout is disabled, the branch at line 138 writes without installing this listener.
Information Checklist
- Bug Description Added
- Repro Steps Added
- Setup information Added
- 主要言語
- Java
- スター
- 2.6k
- フォーク
- 2.2k
- 平均マージ
- 2日 1時間
- マージ済み PR(30日)
- 229
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Azure/azure-sdk-for-java のほかの issue
-
[Spring Cloud Azure] Improve Javadoc and startup guidance for allowed-group-names vs allowed-group-ids in AadAuthenticationProperties対応中かも @himanchalkaushale が 2 日前に担当しました。 オープンazure-spring azure-spring-aad Client
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
Azure/azure-sdk-for-java#51046 · コメント 1 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
mgmt, in track 1 migration guide, call out that file-based authentication method is not recommended再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンAzure.Identity
難易度 1/5 1時間未満 初心者へのやさしさ 74/100
Azure/azure-sdk-for-java#48894 ·
メンテナーはふだん 1 日以内に返信
-
[BUG] Cosmos: `byPage(token, size).next()` sends an extra speculative query for the next page (~2x queries/RU per page call)対応中かも @FabianMeiswinkel が 2 日前に担当しました。 オープンClient Cosmos customer-reported needs-team-attention question Service Attention
Azure/azure-sdk-for-java#51034 · コメント 3 件 · リアクション 1 件 · 担当者 2 名 ·
メンテナーはふだん 1 日以内に返信
-
[FEATURE REQ] Support minor version bump in patch release process対応中かも @jairmyree が 4 日前に担当しました。 オープン
Azure/azure-sdk-for-java#51013 · リアクション 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
[Spring Cloud Azure] Validate tfp/acr claim against configured user-flows in AadB2cResourceServerAutoConfiguration対応中かも @domainname が 3 日前に担当しました。 オープンazure-spring azure-spring-aad-b2c Client
難易度 3/5 1〜2日 初心者へのやさしさ 76/100
Azure/azure-sdk-for-java#51008 · リアクション 1 件 · 担当者 3 名 ·
メンテナーはふだん 1 日以内に返信
Azure/azure-sdk-for-java の issue をすべて見る
似ている issue
-
Type/Bug
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
ballerina-platform/ballerina-library#9458 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
winder/Universal-G-Code-Sender#3242 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
PCL-Community/PCL-CE#3767 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
-
The register's e-mail column is wider in Firefox, and the fee buttons fall outside the table at 900 px対応中かも @AlexanderReaper7 が今日担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
AlexanderReaper7/teaterihuskvarna#170 ·
メンテナーはふだん 2 日以内に返信