diff --git a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java
index 060bef8dde28..1e7068263d73 100644
--- a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java
+++ b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java
@@ -96,12 +96,13 @@ public URI getURI() {
 	@Override
 	protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException {
 		CompletableFuture<HttpResponse<InputStream>> responseFuture = null;
+		TimeoutHandler timeoutHandler = null;
 		try {
 			HttpRequest request = buildRequest(headers, body);
 			responseFuture = this.httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream());
 
 			if (this.timeout != null) {
-				TimeoutHandler timeoutHandler = new TimeoutHandler(responseFuture, this.timeout);
+				timeoutHandler = new TimeoutHandler(responseFuture, this.timeout);
 				HttpResponse<InputStream> response = responseFuture.get();
 				InputStream inputStream = timeoutHandler.wrapInputStream(response);
 				return new JdkClientHttpResponse(response, inputStream);
@@ -136,6 +137,9 @@ else if (cause instanceof IOException ioEx) {
 				throw (message == null ? new IOException(cause) : new IOException(message, cause));
 			}
 		}
+		catch (CancellationException ex) {
+			throw new HttpTimeoutException("Request timed out");
+		}
 	}
 
 	private HttpRequest buildRequest(HttpHeaders headers, @Nullable Body body) {
@@ -224,6 +228,7 @@ public ByteBuffer map(byte[] b, int off, int len) {
 	private static final class TimeoutHandler {
 
 		private final CompletableFuture<Void> timeoutFuture;
+		private boolean isTimeout=false;
 
 		private TimeoutHandler(CompletableFuture<HttpResponse<InputStream>> future, Duration timeout) {
 
@@ -232,6 +237,7 @@ private TimeoutHandler(CompletableFuture<HttpResponse<InputStream>> future, Dura
 
 			this.timeoutFuture.thenRun(() -> {
 				if (future.cancel(true) || future.isCompletedExceptionally() || !future.isDone()) {
+					this.isTimeout = true;
 					return;
 				}
 				try {