Always bind the exchange ID to the execution context
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
index c9001b2..70d7a47 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
@@ -656,6 +656,7 @@
                 try {
                     final SimpleHttpResponse cacheResponse = generateCachedResponse(request, context, entry, now);
                     final String exchangeId = ExecSupport.getNextExchangeId();
+                    context.setExchangeId(exchangeId);
                     final AsyncExecChain.Scope fork = new AsyncExecChain.Scope(
                             exchangeId,
                             scope.route,
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
index 801f5a7..3f756fe 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
@@ -278,6 +278,7 @@
                         && validityPolicy.mayReturnStaleWhileRevalidating(entry, now)) {
                     LOG.debug("Serving stale with asynchronous revalidation");
                     final String exchangeId = ExecSupport.getNextExchangeId();
+                    context.setExchangeId(exchangeId);
                     final ExecChain.Scope fork = new ExecChain.Scope(
                             exchangeId,
                             scope.route,
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
index c4fd294..9496a32 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
@@ -188,12 +188,12 @@
                         httpHost != null ? httpHost : RoutingSupport.determineHost(request),
                         clientContext);
                 final String exchangeId = ExecSupport.getNextExchangeId();
+                clientContext.setExchangeId(exchangeId);
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("{} preparing request execution", exchangeId);
                 }
                 final AsyncExecRuntime execRuntime = createAsyncExecRuntime(pushHandlerFactory);
 
-                clientContext.setExchangeId(exchangeId);
                 setupContext(clientContext);
 
                 final AsyncExecChain.Scheduler scheduler = this::executeScheduled;
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java
index a88b26e..a4bbee6 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java
@@ -213,7 +213,10 @@
                         };
                         if (LOG.isDebugEnabled()) {
                             final String exchangeId = ExecSupport.getNextExchangeId();
-                            LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(session));
+                            clientContext.setExchangeId(exchangeId);
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(session));
+                            }
                             session.enqueue(
                                     new RequestExecutionCommand(
                                             new LoggingAsyncClientExchangeHandler(LOG, exchangeId, internalExchangeHandler),
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
index 0363c86..6a7bb4e 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
@@ -136,6 +136,7 @@
         final HttpRoute route = new HttpRoute(RoutingSupport.normalize(host, schemePortResolver));
         final ComplexFuture<AsyncConnectionEndpoint> resultFuture = new ComplexFuture<>(callback);
         final String exchangeId = ExecSupport.getNextExchangeId();
+        clientContext.setExchangeId(exchangeId);
         final Future<AsyncConnectionEndpoint> leaseFuture = manager.lease(
                 exchangeId,
                 route,
@@ -445,16 +446,18 @@
                 final HttpContext context) {
             Asserts.check(!released.get(), "Endpoint has already been released");
 
+            final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
             final String exchangeId = ExecSupport.getNextExchangeId();
+            clientContext.setExchangeId(exchangeId);
             if (LOG.isDebugEnabled()) {
                 LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(connectionEndpoint));
                 connectionEndpoint.execute(
                         exchangeId,
                         new LoggingAsyncClientExchangeHandler(LOG, exchangeId, exchangeHandler),
                         pushHandlerFactory,
-                        context);
+                        clientContext);
             } else {
-                connectionEndpoint.execute(exchangeId, exchangeHandler, context);
+                connectionEndpoint.execute(exchangeId, exchangeHandler, clientContext);
             }
         }
 
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
index da5a188..699784d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
@@ -159,6 +159,7 @@
                     target != null ? target : RoutingSupport.determineHost(request),
                     localcontext);
             final String exchangeId = ExecSupport.getNextExchangeId();
+            localcontext.setExchangeId(exchangeId);
             if (LOG.isDebugEnabled()) {
                 LOG.debug("{} preparing request execution", exchangeId);
             }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
index b6f4230..24f8b9d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
@@ -132,6 +132,7 @@
 
         final HttpRoute route = new HttpRoute(RoutingSupport.normalize(target, schemePortResolver));
         final String exchangeId = ExecSupport.getNextExchangeId();
+        clientContext.setExchangeId(exchangeId);
         final ExecRuntime execRuntime = new InternalExecRuntime(LOG, connManager, requestExecutor,
                 request instanceof CancellableDependency ? (CancellableDependency) request : null);
         try {