esp_http_client appears to cause a memory leak in RTOS task
Posted: Wed Aug 19, 2026 6:13 pm
Hello all, it's my first time posting here. Hope you are doing well.
I'm writing some firmware for a project, which has to make an HTTP GET request to a server, to get a JSON response. Of course, to do that, I'm using the esp_http_client.
This function (void fetch_schedule_from_alim), is called from inside an RTOS task which runs on an interval. Every 10 seconds (for testing, this will later be 10 minutes but thats irrelevant), that RTOS task reruns, and at some point inside that loop it calls the fetch_schedule_from_alim function. After a lot of logging and debugging, I'm almost 100% certain that the memory leak is not being caused by the task itself, but this function specifically.
The memory leak isn't huge, its around 400 bytes usually, but it varies, sometimes its close to just 100, other times its almost a kilobyte, which suggests that this clearly isn't something simple like a malloc() call not being free'd, since that would be the same amount every time and wouldn't fluctuate.
This is the tetch_schedule_trom_alim function:
As you can see at the end, I'm calling all the cleanup functions for the http_client, so I'm not quite certain what exactly is not being free'd up.
At the top of the RTOS task, I've got a log line which reports the free heap size. Here is that log:
The free heap went from 345972 to 345568 to 345140 to 344944 in just 4 re-runs of the task.
I'm at a loss and I would greatly appreciate any help. Thanks in advance, and sorry if this might be a simpler question than I think, I'm fairly new to this.
I'm writing some firmware for a project, which has to make an HTTP GET request to a server, to get a JSON response. Of course, to do that, I'm using the esp_http_client.
This function (void fetch_schedule_from_alim), is called from inside an RTOS task which runs on an interval. Every 10 seconds (for testing, this will later be 10 minutes but thats irrelevant), that RTOS task reruns, and at some point inside that loop it calls the fetch_schedule_from_alim function. After a lot of logging and debugging, I'm almost 100% certain that the memory leak is not being caused by the task itself, but this function specifically.
The memory leak isn't huge, its around 400 bytes usually, but it varies, sometimes its close to just 100, other times its almost a kilobyte, which suggests that this clearly isn't something simple like a malloc() call not being free'd, since that would be the same amount every time and wouldn't fluctuate.
This is the tetch_schedule_trom_alim function:
Code: Select all
esp_err_t fetch_schedule_from_alim(const char *auth_header, char *out_buf,
size_t out_buf_size) {
// check if the arguments are invalid
if (out_buf == NULL || out_buf_size == 0)
return ESP_ERR_INVALID_ARG;
// always return a valid empty string, so the caller never parses an
// uninitialized buffer
out_buf[0] = '\0';
// the esp_http_client configuration
const esp_http_client_config_t config = {
.url = "[the URL here. ive removed it to post it on the forum]",
.method = HTTP_METHOD_GET,
.timeout_ms = 10000,
.crt_bundle_attach = esp_crt_bundle_attach};
// init the client and the handle
const esp_http_client_handle_t client = esp_http_client_init(&config);
if (!client)
return ESP_FAIL;
// set the auth header
esp_http_client_set_header(client, "Authorization", auth_header);
// open the client
const esp_err_t err = esp_http_client_open(client, 0);
// check if it errored
if (err != ESP_OK) {
ESP_LOGE(TAG, "http client open failed: %s", esp_err_to_name(err));
esp_http_client_cleanup(client);
return err;
}
// read response headers and status code
esp_http_client_fetch_headers(client);
const unsigned int status = esp_http_client_get_status_code(client);
// read the response body into the buffer
int total = 0;
while (total < (int)out_buf_size - 1) {
int r =
esp_http_client_read(client, out_buf + total, out_buf_size - 1 - total);
if (r <= 0)
break;
total += r;
}
out_buf[total] = '\0';
// close the client and clean everything up
esp_http_client_close(client);
esp_http_client_clear_response_buffer(client);
esp_http_client_cleanup(client);
// log whether it worked and return OK or FAIL
ESP_LOGI(TAG, "status=%d, got %d bytes", status, total);
return (status == 200) ? ESP_OK : ESP_FAIL;
}
As you can see at the end, I'm calling all the cleanup functions for the http_client, so I'm not quite certain what exactly is not being free'd up.
At the top of the RTOS task, I've got a log line which reports the free heap size. Here is that log:
Code: Select all
W (155344) RTOS_FETCH_TASK: Hello from the fetch_task. FREE HEAP: 345972)
[more logs...]
W (195914) RTOS_FETCH_TASK: Hello from the fetch_task. FREE HEAP: 345568)
[more logs...]
W (235374) RTOS_FETCH_TASK: Hello from the fetch_task. FREE HEAP: 345140)
[more logs...]
W (275074) RTOS_FETCH_TASK: Hello from the fetch_task. FREE HEAP: 344944)
The free heap went from 345972 to 345568 to 345140 to 344944 in just 4 re-runs of the task.
I'm at a loss and I would greatly appreciate any help. Thanks in advance, and sorry if this might be a simpler question than I think, I'm fairly new to this.