Fix ESP8266 “Soft WDT reset” (random reboots)
Your code ran for about 3 seconds without giving the Wi-Fi stack a turn. Break long loops with yield() or delay(), and give every wait a timeout.
Community draft — report a mistake
What you see
Waiting for sensor...
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
Soft WDT reset
Exception (4):
epc1=0x40201094 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
>>>stack>>>
ctx: cont
sp: 3ffffe20 end: 3fffffd0 offset: 0160
3fffff80: 3fffdad0 00000000 3ffee5a4 402010b9
3fffff90: feefeffe feefeffe feefeffe 40202a5c
<<<stack<<<
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
ets Jan 8 2013,rst cause:2, boot mode:(3,6)Waiting for sensor... --------------- CUT HERE FOR EXCEPTION DECODER --------------- Soft WDT reset Exception (4): epc1=0x40201094 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000 >>>stack>>> ctx: cont sp: 3ffffe20 end: 3fffffd0 offset: 0160 3fffff80: 3fffdad0 00000000 3ffee5a4 402010b9 3fffff90: feefeffe feefeffe feefeffe 40202a5c <<<stack<<< --------------- CUT HERE FOR EXCEPTION DECODER --------------- ets Jan 8 2013,rst cause:2, boot mode:(3,6)
The ESP8266 runs your sketch and its Wi-Fi stack on the same CPU, taking turns. Every time loop() returns, or you call delay() or yield(), the Wi-Fi stack gets its turn and the watchdog is fed. Hold the CPU for about 3 seconds without that, and the software watchdog reboots the board.
// Before: freezes forever if the server never answers
while (!client.available()) {}
// After: yields while waiting, and gives up after 5 s
unsigned long t0 = millis();
while (!client.available() && millis() - t0 < 5000) {
delay(10);
}Quick fix — try in order
- 1
Find the loop that never ends
Typical culprits:
while (!client.available()) {},while (digitalRead(pin) == HIGH) {},while (Serial.available() == 0) {}, or a longforloop doing maths or LED effects. - 2
Add yield() or delay() inside long loops
while (!client.available()) { delay(1); }. Bothdelay()andyield()let the core run Wi-Fi and feed the watchdog. Every return from loop() does too. - 3
Give every wait a timeout
unsigned long t0 = millis(); while (!client.available() && millis() - t0 < 5000) delay(10);— a server that never answers can’t freeze the board. - 4
Keep interrupt handlers tiny
An ISR that does Serial prints or delays runs with the watchdog unable to be fed. Set a flag in the ISR and do the work in loop().
- 5
Decode the stack if it isn’t obvious
Paste the text between the CUT HERE lines into an ESP8266 exception decoder to get the function and line that was running.
Why it happens
Soft WDT versus hardware WDT
The software watchdog fires after about 3.2 s without a yield and prints “Soft WDT reset”. If interrupts are also blocked, the hardware watchdog fires after about 8 s with rst cause:4 and no stack dump.
Why does the ESP32 not do this?
The ESP32 runs Wi-Fi on its own FreeRTOS task, so a busy loop only triggers its task watchdog in some cases. The ESP8266 has a single thread: your loop must hand control back.
Exception (4) after Soft WDT reset
That is how the core reports the watchdog interrupt itself — the exception number is not a separate bug.
Board-specific notes
ESP8266: Blocking libraries (some DHT, OneWire and display drivers) are fine — they finish in milliseconds. It is unbounded waits that cause resets.
ESP32: The ESP32 equivalent is Task watchdog got triggered.
Did this fix it?
Thanks — that helps us keep this page right.