How to fix ESP32 HTTP server refusing connections / connect timeouts (lru_purge_enable)

Problem

Your ESP32 esp_http_server works for a while, then new connections time out — curl hangs, the browser can’t load the web UI — even though the device still responds to ping and earlier connections work fine.

Cause

esp_http_server limits concurrent sockets with max_open_sockets (default: 7). Browsers and keep-alive clients leave sockets open; clients that disappear without a clean close leave them lingering. Once all 7 slots are occupied by stale connections, new connections are accepted by TCP but never serviced — they just time out.

Solution

Enable LRU purging so the server evicts the least-recently-used idle socket when it needs a slot for a new connection, and raise the handler/stack limits while you’re at it:

HTTPServerWrapper.cpp
httpd_config_t conf = HTTPD_DEFAULT_CONFIG();

// Evict stale/idle sockets instead of starving new connections
conf.lru_purge_enable = true;

// Default is 8 — far too low if you have many endpoints
conf.max_uri_handlers = 128;

// Complex handlers (files, JSON) need more than the default 4 KiB
conf.stack_size = 16 * 1024;

httpd_start(&server, &conf);

Additional tips

  • Close your sockets properly in handlers. A handler that returns without calling httpd_resp_send* can leave the session in a weird state. Always send a response (even an empty one).
  • Bounded timeouts: consider conf.recv_wait_timeout and conf.send_wait_timeout (default 5 s) if clients on lossy networks stall mid-request.
  • Check with netstat on the client side: many CLOSE_WAIT/ESTABLISHED entries to the ESP32 confirm socket exhaustion.

After enabling lru_purge_enable, lingering browser connections no longer starve new clients — no reboot required.


Check out similar posts by category: ESP32 C/C++