Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Watchdog · ESP8266

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.

ESP8266 NodeMCUWemos D1 MiniESP-01Updated 3 Nov 2026

Community draft — report a mistake

What you see

OutputOutput
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. 1

    Find the loop that never ends

    Typical culprits: while (!client.available()) {}, while (digitalRead(pin) == HIGH) {}, while (Serial.available() == 0) {}, or a long for loop doing maths or LED effects.

  2. 2

    Add yield() or delay() inside long loops

    while (!client.available()) { delay(1); }. Both delay() and yield() let the core run Wi-Fi and feed the watchdog. Every return from loop() does too.

  3. 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. 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. 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.

↑↓ to move · Enter to open