From dbe8e39aa92214deac6395d89bf5a48dae7ecb61 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 11 Feb 2026 17:03:07 -0600 Subject: [PATCH] [web_server_idf] Move multipart upload buffer back to heap to fix httpd stack overflow The 1460-byte MULTIPART_CHUNK_SIZE buffer was moved from heap to stack in #13549, but the httpd task stack is only ~4096-5632 bytes. This causes a stack overflow crash when processing OTA uploads, especially on configs with BLE components that add additional stack pressure. Move it back to heap since this buffer is only used during OTA uploads (not a hot path), so heap fragmentation is not a concern here. Fixes stack overflow: "A stack overflow in task httpd has been detected" --- esphome/components/web_server_idf/web_server_idf.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/web_server_idf/web_server_idf.cpp b/esphome/components/web_server_idf/web_server_idf.cpp index 2e07fb6e0a..d7d6f90355 100644 --- a/esphome/components/web_server_idf/web_server_idf.cpp +++ b/esphome/components/web_server_idf/web_server_idf.cpp @@ -881,12 +881,12 @@ esp_err_t AsyncWebServer::handle_multipart_upload_(httpd_req_t *r, const char *c } }); - // Process data - use stack buffer to avoid heap allocation - char buffer[MULTIPART_CHUNK_SIZE]; + // Use heap buffer - 1460 bytes is too large for the httpd task stack + auto buffer = std::make_unique(MULTIPART_CHUNK_SIZE); size_t bytes_since_yield = 0; for (size_t remaining = r->content_len; remaining > 0;) { - int recv_len = httpd_req_recv(r, buffer, std::min(remaining, MULTIPART_CHUNK_SIZE)); + int recv_len = httpd_req_recv(r, buffer.get(), std::min(remaining, MULTIPART_CHUNK_SIZE)); if (recv_len <= 0) { httpd_resp_send_err(r, recv_len == HTTPD_SOCK_ERR_TIMEOUT ? HTTPD_408_REQ_TIMEOUT : HTTPD_400_BAD_REQUEST, @@ -894,7 +894,7 @@ esp_err_t AsyncWebServer::handle_multipart_upload_(httpd_req_t *r, const char *c return recv_len == HTTPD_SOCK_ERR_TIMEOUT ? ESP_ERR_TIMEOUT : ESP_FAIL; } - if (reader->parse(buffer, recv_len) != static_cast(recv_len)) { + if (reader->parse(buffer.get(), recv_len) != static_cast(recv_len)) { ESP_LOGW(TAG, "Multipart parser error"); httpd_resp_send_err(r, HTTPD_400_BAD_REQUEST, nullptr); return ESP_FAIL;