diff --git a/components/esp_http_server/src/httpd_main.c b/components/esp_http_server/src/httpd_main.c
index a1006feb368..fd434e87ae1 100644
--- a/components/esp_http_server/src/httpd_main.c
+++ b/components/esp_http_server/src/httpd_main.c
@@ -254,6 +254,11 @@ static int httpd_process_session(struct sock_db *session, void *context)
         return 1;
     }
 
+    // session is busy in an async task, do not process here.
+    if (session->for_async_req) {
+        return 1;
+    }
+
     process_session_context_t *ctx = (process_session_context_t *)context;
     int fd = session->fd;
 
diff --git a/components/esp_http_server/src/httpd_sess.c b/components/esp_http_server/src/httpd_sess.c
index a10c62fb1a1..ac03edf8d15 100644
--- a/components/esp_http_server/src/httpd_sess.c
+++ b/components/esp_http_server/src/httpd_sess.c
@@ -72,6 +72,7 @@ static int enum_function(struct sock_db *session, void *context)
     case HTTPD_TASK_INIT:
         session->fd = -1;
         session->ctx = NULL;
+        session->for_async_req = false;
         break;
     // Get active session
     case HTTPD_TASK_GET_ACTIVE:
@@ -87,7 +88,7 @@ static int enum_function(struct sock_db *session, void *context)
         break;
     // Set descriptor
     case HTTPD_TASK_SET_DESCRIPTOR:
-        if (session->fd != -1) {
+        if (session->fd != -1 && !session->for_async_req) {
             FD_SET(session->fd, ctx->fdset);
             if (session->fd > ctx->max_fd) {
                 ctx->max_fd = session->fd;
diff --git a/components/esp_http_server/src/httpd_txrx.c b/components/esp_http_server/src/httpd_txrx.c
index ad5e8ed9739..fa50378f69e 100644
--- a/components/esp_http_server/src/httpd_txrx.c
+++ b/components/esp_http_server/src/httpd_txrx.c
@@ -631,9 +631,11 @@ esp_err_t httpd_req_async_handler_begin(httpd_req_t *r, httpd_req_t **out)
     }
     memcpy(async_aux->resp_hdrs, r_aux->resp_hdrs, hd->config.max_resp_headers * sizeof(struct resp_hdr));
 
+    // Prevent the main thread from reading the rest of the request after the handler returns.
+    r_aux->remaining_len = 0;
+
     // mark socket as "in use"
-    struct httpd_req_aux *ra = r->aux;
-    ra->sd->for_async_req = true;
+    r_aux->sd->for_async_req = true;
 
     *out = async;