Http_request set Error flag: unspecified

Hello, I have made a ESPHome configuration with some help of Gemini, which works pretty good. After a time, could be minutes but also hours, suddenly I get the following error:

[22:18:02.170][D][esp-idf:000]: E (851940) transport_base: tcp_read error, errno=Connection reset by peer
[22:18:02.177][E][http_request.idf:207]: HTTP Request failed; URL: http://192.168.1.155/api/v1/data; Code: -1
[22:18:02.178][E][component:314]: http_request set Error flag: unspecified

In the configuration I also try to prevent crashing the ESP on these errors, but the ESP stops working and responding:

              # HANDEL FOUTEN AF:
              on_error:
                then:
                  - lambda: |-
                      ESP_LOGW("http_request", "Lader 1 data request failed!");
                      // Zet de sensor status op 'ongeldig' (NaN)
                      id(lader1_power_raw).publish_state(NAN);

Even the reboot after 3 min does not work:

 # Enable Home Assistant API
api:
  # Herstart de ESP32 als deze langer dan 3 minuten geen API-verbinding heeft met Home Assistant
  reboot_timeout: 3min 

The only thing that solves is disconnecting the power, wait 10 seconds and start all over.

Is there a solution to prevent the ESP crashing?

## Algemene configuratie ## 
esphome:
  name: esp-laad-control
  friendly_name: esp-laad-control
  comment: Laad control accu

# Gebruik substitutions voor centrale waarden
substitutions:
  max_charger_power: '1500.0' # Maximaal ladervermogen in Watt
  dac_voltage_range: '3.3'    # Maximale DAC spanning in Volt

esp32:
  board: esp32dev
  variant: esp32 
  framework:
    type: esp-idf

# Enable logging
logger:
  # Niveau WARN is goed voor productie, INFO voor debuggen
  level: DEBUG 

# Enable Home Assistant API
api:
  # Herstart de ESP32 als deze langer dan 3 minuten geen API-verbinding heeft met Home Assistant
  reboot_timeout: 3min 

# Enable OTA
ota:
  - platform: esphome

# Enable wifi en andere basiscomponenten
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: light

# Enable fallback hotspot
  ap:
    ssid: "Esp-Laad-Control"
    password: !secret wifi_hotspot_password
    ap_timeout: 5min

captive_portal:

# Webserver is uitgecommentarieerd
#web_server:
# port: 80

# Create restart button
button:
  - platform: restart
    id: restart_button
    name: "Herstart Esp-Laad-Control module"

# 1. Configureer de DAC-uitgang (GPIO25 of GPIO26) VOORDAT deze gebruikt wordt
output:
  - platform: esp32_dac
    pin: GPIO25
    id: load_control_dac
    zero_means_zero: true

# 2. Configureer een "Number" entiteit voor DAC niveau
number:
  - platform: template
    name: "4 DAC Output Level 0 <-> 1 (GPIO25)"
    id: dac_level
    min_value: 0.0
    max_value: 33.80 
    step: 0.01
    optimistic: true

# 3. DEFINIEER ALLE SENSORS
sensor:
  - platform: template
    id: p1_usage_raw
    name: "1 P1 Usage Power Raw"
    unit_of_measurement: W
    icon: mdi:transmission-tower

  - platform: template
    id: lader1_power_raw
    name: "2 Lader 1 Power Raw"
    unit_of_measurement: W
    icon: mdi:battery-charging-high

  # Berekende Overshoot sensor
  - platform: template
    name: "3 Power Overshoot"
    unit_of_measurement: W
    id: power_overschot
    icon: mdi:transmission-tower-export

# 4. Data Ophalen en Laadregeling
### HTTP Request Configuratie
http_request:
  timeout: 4.5s
  verify_ssl: false
  # Buffer size van 2048 is waarschijnlijk prima voor deze JSON responses
  buffer_size_rx: 2048

### Tijdgebaseerde Acties (SNTP)
time:
  - platform: sntp
    on_time:
      - seconds: /1
        then:
          # 1. HTTP Request voor P1 data
          - http_request.get:
              url: http://192.168.1.115/api/v1/data
              capture_response: True
              on_response:
                then:
                  - lambda: |-
                      json::parse_json(body, [](JsonObject root) -> bool {
                        // Publiceer de waarde direct naar de sensor ID
                        id(p1_usage_raw).publish_state(root["active_power_w"]);
                        return true;
                      });
              # HANDEL FOUTEN AF:
              on_error:
                then:
                  - lambda: |-
                      ESP_LOGW("http_request", "P1 data request failed!");
                      // Zet de sensor status op 'ongeldig' (NaN) zodat de logica weet dat er iets mis is
                      id(p1_usage_raw).publish_state(NAN);

          # 2. HTTP Request voor Lader 1 data
          - http_request.get:
              url: http://192.168.1.155/api/v1/data
              capture_response: True
              on_response:
                then:
                  - lambda: |-
                      json::parse_json(body, [](JsonObject root) -> bool {
                       // Publiceer de waarde direct naar de sensor ID
                       id(lader1_power_raw).publish_state(root["active_power_w"]);
                       return true;
                      });
              # HANDEL FOUTEN AF:
              on_error:
                then:
                  - lambda: |-
                      ESP_LOGW("http_request", "Lader 1 data request failed!");
                      // Zet de sensor status op 'ongeldig' (NaN)
                      id(lader1_power_raw).publish_state(NAN);

          # 3. Laadregel Logica (Gebruikt de 'load_control_dac' ID)
          # Deze logica moet nu controleren of de sensoren geldig zijn
          - if:
              condition: 
                # Controleer of beide sensoren een geldige waarde hebben EN of er overschot is
                lambda: return id(p1_usage_raw).has_state() && id(lader1_power_raw).has_state() && id(p1_usage_raw).state < 0;
              then:
                - output.set_level:
                    id: load_control_dac 
                    level: !lambda |-
                      // Bereken de werkelijke power overshoot (altijd positief getal)
                      float power_overshoot = - (id(p1_usage_raw).state) + (id(lader1_power_raw).state);

                      // Publiceer de overshoot naar de sensor
                      id(power_overschot).publish_state(power_overshoot);

                      // Bereken de schaal: (overschot / max_power) -> dit geeft 0.0 tot 1.0
                      // Gebruik de substitution variabele
                      float scaled_level = power_overshoot / ${max_charger_power};

                      // Publiceer de schaal naar de number entiteit
                      id(dac_level).publish_state(scaled_level * 33.80);

                      // Zorg ervoor dat de waarde begrensd is tussen 0.0 en 1.0 (clamping)
                      return std::min((float)1.0, std::max((float)0.0, scaled_level));

              # Wat te doen als er GÉÉN overschot is OF als de sensoren ongeldig zijn
              else:
                # Zet de DAC-output naar 0
                - output.set_level:
                    id: load_control_dac
                    level: 0.0 # Vereenvoudigd van !lambda return 0;
                # Update ook de sensors naar 0 als er geen overschot is
                - lambda: |-
                    id(power_overschot).publish_state(0.0);
                    id(dac_level).publish_state(0.0);

Thanks!

So power cycle (disconnect) of 0.5s doesn’t work?

No, minimal I found is 5 seconds is needed

I tried this as well, but does not solve the problem either:

Oke, I found that the socket on IP-address 192.168.1.155 is faulty. When I use a another socket, the ESPHome configuration works perfect.

What I just don’t understand is why the ESP32 crashes. I have build in error-handeling, but it seems not working. As soon as I get a Code: -1 the ESP32 stops responding, and I have to power-cycle it.

Error handeling:

              on_error:
                then:
                  - lambda: |-
                      ESP_LOGW("http_request", "Lader 1 data request failed!");
                      // Zet de sensor status op 'ongeldig' (NaN)
                      id(lader1_power_raw).publish_state(NAN);

How can I prevent this?

Thanks!

Well problem not solved. I do have the problem as well with the P1 meter and other sockets.
I have set the lease time for DHCP to 2d, which also does not solve the problem.

Does nobody know how handeling a error message in these http_requests?

How it behaves if you change the time interval to 5s ?

I had the exact same issue for month, and hopped the 2025.11 would resolve this, it didn’t.
I also monitor heap, it doesn’t seam like a memory issue.
I don’t need to unplug for 10s tho, i use the reset button on device and this work.

but other than that, exact same beaviour, random time, immediate crash after error 1

[17:46:50.636][D][http_request.idf:043]: Received response header, name: content-length, value: 229
[17:46:50.715][D][http_request.idf:043]: Received response header, name: content-type, value: application/json
[17:46:50.719][D][http_request.idf:043]: Received response header, name: content-length, value: 239
[17:46:50.770][D][http_request.idf:043]: Received response header, name: content-type, value: application/json
[17:46:50.773][D][http_request.idf:043]: Received response header, name: content-length, value: 220
[17:46:55.408][D][http_request.idf:043]: Received response header, name: content-type, value: application/json
[17:46:55.410][D][http_request.idf:043]: Received response header, name: content-length, value: 220
[17:47:01.114][E][http_request.idf:208]: HTTP Request failed; URL: http://192.168.2.30/rpc/Light.GetStatus?id=1; Code: -1
[17:47:01.115][E][component:315]: http_request set Error flag: unspecified
INFO Processing unexpected disconnect from ESPHome API for kc868-ai-light-controler @ 192.168.2.50
WARNING Disconnected from API
INFO Successfully resolved kc868-ai-light-controler @ 192.168.2.50 in 0.142s
INFO Successfully connected to kc868-ai-light-controler @ 192.168.2.50 in 0.005s

The code

script:
  - id: shelly_api_Light_GetStatus
    mode: parallel
    parameters:
      ip: string
      light_id: int
      status_index: int
    then:
      - http_request.get:
          url: !lambda 'return str_sprintf("http://%s/rpc/Light.GetStatus?id=%d", ip.c_str(), light_id);'
          capture_response: true
          request_headers:
            Content-Type: application/json
          on_response:
            then:
              - lambda: |-
                  json::parse_json(body, [status_index](JsonObject root) -> bool {
                      if (root.containsKey("output") && root.containsKey("brightness")) {
                          id(dimmer_outputs)[status_index] = root["output"].as<std::string>();
                          id(dimmer_brightnesses)[status_index] = root["brightness"].as<std::string>();
                          return true;
                      }
                      return false;
                  });
          on_error:
            then:
              - logger.log: "Request to Shelly failed!"

The heap

At the resquest of someone on the discord, i ran it with usb serial, to see if anything showed up after the error but couldn’t be seen because of a network issue.

Sadly, no

e[0;36m[D][http_request.idf:043]: Received response header, name: content-type, value: application/jsone[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-length, value: 229e[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-type, value: application/jsone[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-length, value: 239e[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-type, value: application/jsone[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-length, value: 222e[0m
e[0;36m[D][internal_temperature:075]: Ignoring invalid temperature (success=0, value=53.3)e[0m
e[0;36m[D][sensor:133]: 'Heap Free': Sending state 198780.00000 B with 0 decimals of accuracye[0m
e[0;36m[D][sensor:133]: 'Device Uptime': Sending state 56261.30078 s with 0 decimals of accuracye[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-type, value: application/jsone[0m
e[0;36m[D][http_request.idf:043]: Received response header, name: content-length, value: 221e[0m
e[1;31m[E][http_request.idf:208]: HTTP Request failed; URL: http://192.168.2.30/rpc/Light.GetStatus?id=1; Code: -1e[0m
e[1;31m[E][component:315]: http_request set Error flag: unspecifiede[0m

I think we need to open an issue on github, but we need to make it simpler, and find a dev ready to wait hours if not day to wait for a crash

Same, it’s indepent of the time interval… I use a interval of 10 seconds now, same problem…

Strange like we are the only two. I can’t find any others.

What do you mean with make it simpler?

a minimal esphome file with only the bare minimum an the http_request to a public internet api so that it can be quickly reproduce by anyone

I tried after this commit just to be sure, not better

I made something simple to reproduce and did it on another device

[23:13:02.274][D][http_request.idf:043]: Received response header, name: content-type, value: application/json; charset=utf-8
[23:13:02.277][D][http_request.idf:043]: Received response header, name: content-length, value: 221
[23:13:02.285][D][script_01:050]: Check id: yh6f0r4529hb
[23:13:02.287][D][script_01:051]: Check status: minor
[23:13:07.275][D][http_request.idf:043]: Received response header, name: content-type, value: application/json; charset=utf-8
[23:13:07.278][D][http_request.idf:043]: Received response header, name: content-length, value: 221
[23:13:07.284][D][script_01:050]: Check id: yh6f0r4529hb
[23:13:07.287][D][script_01:051]: Check status: minor
[23:13:12.313][D][http_request.idf:043]: Received response header, name: content-type, value: application/json; charset=utf-8
[23:13:12.316][D][http_request.idf:043]: Received response header, name: content-length, value: 221
[23:13:12.324][D][script_01:050]: Check id: yh6f0r4529hb
[23:13:12.326][D][script_01:051]: Check status: minor
[23:13:17.291][D][http_request.idf:043]: Received response header, name: content-type, value: application/json; charset=utf-8
[23:13:17.294][D][http_request.idf:043]: Received response header, name: content-length, value: 221
[23:13:17.301][D][script_01:050]: Check id: yh6f0r4529hb
[23:13:17.303][D][script_01:051]: Check status: minor
[23:13:22.318][D][http_request.idf:043]: Received response header, name: content-type, value: application/json; charset=utf-8
[23:13:22.318][D][http_request.idf:043]: Received response header, name: content-length, value: 221
[23:13:22.318][D][script_01:050]: Check id: yh6f0r4529hb
[23:13:22.318][D][script_01:051]: Check status: minor
[23:13:31.772][E][http_request.idf:208]: HTTP Request failed; URL: https://www.cloudflarestatus.com/api/v2/status.json; Code: -1
[23:13:31.774][E][component:315]: http_request set Error flag: unspecified
INFO Processing unexpected disconnect from ESPHome API for test @ 192.168.2.39
WARNING Disconnected from API
INFO Successfully resolved test @ 192.168.2.39 in 0.244s
INFO Successfully connected to test @ 192.168.2.39 in 0.005s
WARNING Can't connect to ESPHome API for test @ 192.168.2.39: Handshake timed out after 30.0s (TimeoutAPIError)
INFO Trying to connect to test @ 192.168.2.39 in the background
INFO Successfully connected to test @ 192.168.2.39 in 0.025s
INFO Successfully connected to test @ 192.168.2.39 in 0.067s
INFO Successfully connected to test @ 192.168.2.39 in 0.037s
esphome:
  name: test
  friendly_name: test

  platformio_options:
    board_build.extra_flags:
      # WIFI_CONTROL_SELF_MODE = 0
      # WIFI_CONTROL_SELF_MODE = 1
      - "-DWIFI_CONTROL_SELF_MODE=1"

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret API_PASS
  reboot_timeout: 0s

ota:
  - platform: esphome
    password: !secret OTA_PASS

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

http_request:
  verify_ssl: False

interval:
  - interval: 5sec
    startup_delay: 10sec
    then:
      - http_request.get:
          url: 'https://www.cloudflarestatus.com/api/v2/status.json'
          capture_response: true
          request_headers:
            Content-Type: application/json
          on_response:
            then:
              - lambda: |-
                  json::parse_json(body, [](JsonObject root) -> bool {
                      if (root.containsKey("page") && root.containsKey("status")) {
                          ESP_LOGD("script_01", "Check id: %s", root["page"]["id"].as<std::string>().c_str());
                          ESP_LOGD("script_01", "Check status: %s", root["status"]["indicator"].as<std::string>().c_str());
                          return true;
                      }
                      return false;
                  });
          on_error:
            then:
              - logger.log: "Request to Cloudflare failed!"

I will try to open an issue next weekend if someone else don’t do it.
This week, i have 9am - 10pm work schedule without launch break … no time for this.