firmware: POST /ota always fails — stack overflow in task httpd during esp_ota_end() image validation (ESP32-S3, v0.8.8)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 94.5k
- Forks
- 12.5k
- Avg merge
- 21h 27m
- Merged PRs (30d)
- 43
Description
Summary
POST /ota never completes on an ESP32-S3-DevKitC-1: the upload transfers fully, then the node hits ***ERROR*** A stack overflow in task httpd has been detected. during image validation and reboots into the old slot. The endpoint is effectively unusable, and the failure is silent from the client side (curl just sees the connection drop).
Environment
| Board | ESP32-S3-DevKitC-1 N16R8 (16 MB flash, 8 MB octal PSRAM) |
| Firmware | built from tag v0.8.8-esp32 |
| sdkconfig | sdkconfig.defaults;sdkconfig.defaults.devkitc (display compiled out) |
| Toolchain | ESP-IDF v5.4 via espressif/idf:v5.4 Docker image |
| App image | 911,232 bytes; ota_0 / ota_1 are 2 MB each |
Reproduction
curl -X POST -H "Authorization: Bearer $PSK" \
-H "Content-Type: application/octet-stream" \
--data-binary @esp32-csi-node.bin http://<node>:8032/ota
Client result: HTTP 000 sent=911232 t=58.7s (connection closed, no response body).
GET /ota/status before and after shows the same running_partition, so nothing was switched.
Console output
I (20046) ota_update: OTA update started, content_length=911232
I (31246) esp_image: segment 0: paddr=00220020 vaddr=3c0a0020 size=23dd8h (146904) map
***ERROR*** A stack overflow in task httpd has been detected.
Backtrace: 0x40375c19:0x3fcc9470 0x4037d579:0x3fcc9490 0x4037e276:0x3fcc94b0
0x4037f837:0x3fcc9530 0x4037e3bc:0x3fcc9550 0x4037e3b2:0x3c0a0020 |<-CORRUPTED
Rebooting...
The overflow happens after the whole body is received, at the point esp_ota_end() runs esp_image_verify() — that validation executes on the httpd task.
Cause
ota_start_server() in main/ota_update.c uses HTTPD_DEFAULT_CONFIG() and overrides max_uri_handlers and recv_wait_timeout, but leaves stack_size at the 4096-byte default. Image verification needs more than that.
This is present both on v0.8.8-esp32 and on main (b370d4f).
Note that docs/TROUBLESHOOTING.md §6 already prescribes this class of fix ("Increase httpd stack from 4KB to 8KB") for a different OTA crash, but ota_update.c never sets it.
Fix that works
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = OTA_PORT;
config.stack_size = 12288; // <-- added
config.max_uri_handlers = 12;
config.recv_wait_timeout = 30;
With this change OTA completes normally on the same hardware and image:
{"status":"ok","message":"OTA update successful. Rebooting..."}
and /ota/status afterwards reports the other slot (ota_0 -> ota_1). Verified repeatedly across three nodes.
8192 may well be enough; 12288 was chosen for headroom and not minimised.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in main/ota_update.c at ota_start_server() and inspect the HTTPD_DEFAULT_CONFIG() values, especially stack_size. Reproduce with the provided curl upload on an ESP32-S3 using the stated firmware setup, then verify that OTA returns success and /ota/status reports the other slot without a reboot. Check docs/TROUBLESHOOTING.md §6 for the existing guidance on HTTPD stack sizing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100