Skip to content
Tutorial
15 min read
October 17, 2026

ESP32 WiFi Not Connecting? Fix Connection Failed, Disconnects & Timeouts

A step-by-step ESP32 WiFi troubleshooting guide: decode status and disconnect reason codes, fix wrong password, 5 GHz, WPA3, weak signal and power problems, and add a robust reconnect and watchdog strategy that keeps your device online.

Few things are more frustrating than an ESP32 that prints dots forever, or one that worked all week and silently went offline overnight. The good news is that nearly every ESP32 WiFi failure falls into a short list of causes, and the chip will usually tell you which one if you ask it the right way.

This guide is a diagnosis tool, not a pile of random tips. First you will make the ESP32 report why it failed, using status codes and disconnect reason codes. Then you will work through the real causes in order of how often they happen: credentials and band, router settings, signal strength, power, DHCP and DNS, and sleep behavior. Finally you will add a reconnect strategy that recovers from outages without a manual reset. If you are new to the basics, start with the ESP32 WiFi tutorial.

Image pending: ESP32 DevKit on a desk with the Serial Monitor showing repeated Connecting dots and a WiFi failure message

Step 1: Make the ESP32 Tell You Why

Do not guess. Register an event handler that prints the disconnect reason code. This one change turns "it does not work" into a specific problem.

#include <WiFi.h>

const char* ssid     = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";

const char* reasonText(uint8_t r) {
  switch (r) {
    case 2:   return "AUTH_EXPIRE (authentication expired)";
    case 4:   return "ASSOC_EXPIRE";
    case 5:   return "ASSOC_TOOMANY (router has no free client slots)";
    case 6:   return "NOT_AUTHED";
    case 8:   return "ASSOC_LEAVE (router disconnected us)";
    case 15:  return "4WAY_HANDSHAKE_TIMEOUT (usually wrong password)";
    case 200: return "BEACON_TIMEOUT (signal lost)";
    case 201: return "NO_AP_FOUND (network not visible)";
    case 202: return "AUTH_FAIL (authentication failed)";
    case 203: return "ASSOC_FAIL";
    case 204: return "HANDSHAKE_TIMEOUT";
    case 205: return "CONNECTION_FAIL";
    default:  return "other";
  }
}

void onWiFiEvent(arduino_event_id_t event, arduino_event_info_t info) {
  switch (event) {
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.println("Associated with the access point");
      break;
    case ARDUINO_EVENT_WIFI_STA_GOT_IP:
      Serial.print("Got IP: ");
      Serial.println(WiFi.localIP());
      break;
    case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: {
      uint8_t r = info.wifi_sta_disconnected.reason;
      Serial.printf("Disconnected, reason %u: %s\n", r, reasonText(r));
      break;
    }
    default:
      break;
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.onEvent(onWiFiEvent);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
}

void loop() {
}

Upload it and read the reason that appears in the Serial Monitor. The table below maps the common ones to a fix.

ReasonWhat it meansGo to
201 NO_AP_FOUNDThe ESP32 cannot see that network nameStep 2 (name, band, range)
15 / 202 / 204Password or security mode problemStep 2 and Step 3
200 BEACON_TIMEOUTSignal dropped or was too weakStep 4
8 ASSOC_LEAVE, 5 ASSOC_TOOMANYThe router kicked it out or is fullStep 3
Connects then loses link repeatedlyPower or signalSteps 4 and 5
Connected, but no internet or no names resolveDHCP or DNSStep 6
Image pending: Serial Monitor output printing the WiFi disconnect reason code and its description from the event handler

Step 2: The Four Most Common Causes (Check These First)

1. Wrong SSID or password. Case matters, spaces matter, and look-alike characters (zero and capital O, lowercase l and capital I) cause endless trouble. Copy the values from your router or phone settings. Reason 15 (handshake timeout) and 202 (auth failure) point here. A trailing space in the password string is invisible and fatal.

2. The network is 5 GHz only. The ESP32 supports 2.4 GHz only. If your router broadcasts the 5 GHz band under a separate name, connect to the 2.4 GHz name. If your router uses one combined name with band steering, the ESP32 normally still works, but turning band steering off or giving the 2.4 GHz band its own name often cures stubborn failures. Reason 201 with a network you can clearly see on your phone is the classic sign.

3. The network is out of range or invisible to the ESP32. Run a scan (see the WiFi tutorial) and check your network appears, with a signal better than about -75 dBm. Hidden networks need the exact name and sometimes a scan on the right channel.

4. Special characters or unusual names. Very long SSIDs, emoji or non-ASCII characters in the network name occasionally cause trouble. A quick test is to create a simple temporary network (for example from a phone hotspot) with a plain name and password. If that works, the issue is in the router's naming or security configuration, not your code.

A very useful experiment: try your phone's hotspot. If the ESP32 connects to the hotspot but not to your router, the code and hardware are fine and the router settings are the problem. On an iPhone, turn on Maximize Compatibility in the hotspot settings so it uses 2.4 GHz.

Image pending: Router WiFi settings page showing separate 2.4 GHz and 5 GHz network names and the band steering option

Step 3: Router Settings That Block the ESP32

SettingProblemFix
WPA3-only or strict WPA3Many ESP32 setups handle WPA2 best, and WPA3-only networks can failUse WPA2-PSK (AES) or a WPA2/WPA3 mixed mode
WPA/TKIP or old WEPInsecure and often refusedSwitch to WPA2 with AES
WPA2-Enterprise (username and login)Needs special enterprise codeUse a separate normal WPA2 network for IoT devices
MAC address filteringThe router silently rejects unknown devicesAdd the ESP32's MAC (print it with WiFi.macAddress()) or turn filtering off
Guest network or AP isolationDevice connects but cannot be reachedDisable client isolation, or use the main network
Maximum client limit reachedReason 5, new devices refusedRemove old devices or raise the limit
Channel 12 to 14Some regions and chips handle high channels poorlySet the 2.4 GHz channel to 1, 6 or 11
802.11n-only or 802.11ax-onlyESP32 is b/g/nAllow 802.11b/g/n mixed mode
Captive portal networks (hotels, cafes)Needs a browser login firstNot suitable without extra work

Printing the ESP32 MAC address is a one-liner:

WiFi.mode(WIFI_STA);
Serial.println(WiFi.macAddress());

Changing router settings can disturb other devices, so change one thing at a time and test.

Step 4: Signal Strength

A device that connects but keeps dropping is very often a weak-signal device. Measure it:

Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());
RSSIMeaning
Better than -60 dBmGood
-60 to -70 dBmAcceptable
-70 to -80 dBmMarginal. Expect drops and slow replies
Worse than -80 dBmUnreliable. Reason 200 (beacon timeout) is typical

What helps, roughly in order of effect:

  1. Move the ESP32 or the router closer, or add an access point or mesh node nearby.
  2. Keep the antenna free. Metal enclosures, ground planes, batteries and thick walls hurt. On boards with a PCB antenna, keep the antenna end of the module clear of other parts.
  3. Use a board with an external antenna connector and a proper antenna for far-away installs.
  4. Pick a clear channel. Neighbors on the same 2.4 GHz channel add interference. Channels 1, 6 and 11 do not overlap.
  5. Keep it away from noise sources such as microwave ovens, motor drivers and USB 3 cables, which radiate in the 2.4 GHz band.

Some very small boards (certain ESP32-C3 mini boards with tiny antennas) connect more reliably if you lower the transmit power with WiFi.setTxPower(WIFI_POWER_8_5dBm); after WiFi.begin(). It sounds backwards, but on a few designs it stops the antenna and regulator from fighting each other. Treat it as a last-resort experiment.

Image pending: Diagram comparing ESP32 placements near a router, behind a wall and inside a metal box with their RSSI values

Step 5: Power Problems Look Exactly Like WiFi Bugs

The WiFi radio draws brief current spikes of several hundred milliamps when it transmits. A weak USB port, a thin or long cable, a cheap charger or a dying battery makes the supply voltage sag, and the chip responds by resetting or dropping the link. The signs:

  • The Serial Monitor shows "Brownout detector was triggered".
  • The board reboots while connecting or while sending data.
  • WiFi works with a short cable on a good charger and fails on a long cable.

Fixes: use a 5V supply rated 1A or more, a short, good-quality USB cable (many cheap ones have thin wires), and add a 470 µF to 1000 µF capacitor across the 5V and GND pins close to the board. Avoid powering the board from a laptop port through a long cable together with a motor or a relay, and never run servos or relays from the ESP32's own 3.3V. Do not disable the brownout detector to hide the symptom: it is warning you about a real problem.

The ESP32-CAM guide explains the same power issue in the context of cameras, where it is even more common.

Image pending: Serial Monitor showing Brownout detector was triggered next to a photo of a 470 microfarad capacitor added across the 5V and GND pins

Step 6: Connected, But Nothing Works (DHCP and DNS)

If the Serial Monitor shows Got IP but requests still fail, the network layer is the issue.

IP is 0.0.0.0. The ESP32 associated with the router but never received an address. The router's DHCP pool may be full, or DHCP is off. Free up addresses, enlarge the pool or reboot the router.

Can reach IP addresses but not names (getaddrinfo fails, HTTP returns -1). DNS is missing. This is the classic result of a static IP configured without DNS servers. Add the DNS arguments to WiFi.config(), as explained in the static IP guide.

Two devices fight and keep dropping. A duplicate IP address. Give each device a unique address or use DHCP reservations.

The device is reachable from one phone and not from another. The two are on different networks or one is on a guest network with isolation.

Test internet reachability from the ESP32 with a short HTTP request (GET and POST guide), and print WiFi.gatewayIP() and WiFi.dnsIP() to confirm they are sensible.

Step 7: It Works for Hours, Then Dies

Long-running failures need a different approach, because you cannot watch the Serial Monitor for three days.

Power saving. The ESP32 uses modem sleep between router beacons by default. On some routers this causes missed packets and slow or lost connections. Turn it off for always-powered devices:

WiFi.setSleep(false);

This costs a little more power but often fixes random latency and drops on mains-powered devices. Do not use it on battery projects. For those, see the deep sleep guide.

Router lease or reboot. After a router restart the ESP32 must notice the loss and reconnect. If your sketch waits forever in a loop that never checks the status, it stays dead. The next section handles this.

Memory leaks. A sketch that slowly loses heap eventually crashes. Print ESP.getFreeHeap() every few minutes. A number that keeps falling points to an object created in a loop and never released (a common culprit is forgetting http.end()).

A Reconnect Strategy That Actually Recovers

This pattern checks the connection regularly, retries with a growing delay, and restarts the chip as a last resort so a device in a remote location never stays offline.

#include <WiFi.h>

const char* ssid     = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";

const unsigned long CHECK_INTERVAL   = 10000;     // check every 10 s
const unsigned long RESTART_AFTER_MS = 600000;    // restart after 10 min offline

unsigned long lastCheck = 0;
unsigned long offlineSince = 0;
unsigned long backoff = 5000;
unsigned long nextAttempt = 0;

void startWiFi() {
  WiFi.disconnect(true);
  delay(100);
  WiFi.mode(WIFI_STA);
  WiFi.setAutoReconnect(true);
  WiFi.persistent(false);          // do not rewrite flash on every connect
  WiFi.begin(ssid, password);
}

void maintainWiFi() {
  if (millis() - lastCheck < CHECK_INTERVAL) return;
  lastCheck = millis();

  if (WiFi.status() == WL_CONNECTED) {
    offlineSince = 0;
    backoff = 5000;
    return;
  }

  if (offlineSince == 0) offlineSince = millis();
  Serial.printf("WiFi down for %lu s, retrying\n", (millis() - offlineSince) / 1000);

  if (millis() >= nextAttempt) {
    startWiFi();
    nextAttempt = millis() + backoff;
    backoff = min(backoff * 2, 60000UL);
  }

  if (millis() - offlineSince > RESTART_AFTER_MS) {
    Serial.println("Offline too long, restarting");
    ESP.restart();
  }
}

void setup() {
  Serial.begin(115200);
  startWiFi();
}

void loop() {
  maintainWiFi();
  // your normal code here
}

The ideas matter more than the exact numbers: check periodically with millis(), back off between attempts so you do not hammer a router that is rebooting, and fall back to a full restart after a long outage. Combine it with the event-based reconnect from the WiFi tutorial if you want instant reaction as well.

For an even stronger safety net, enable the hardware watchdog so a hung sketch resets itself, and publish a heartbeat message (for example over MQTT) so you notice a silent device quickly.

Image pending: Serial Monitor log of the reconnect strategy: WiFi down, increasing retry delays, successful reconnect and backoff reset

Quick Reset Tricks

When a board is stuck in a strange state, these help:

  • Erase stored WiFi settings. WiFi.disconnect(true, true); clears saved credentials and settings, then reconnect with a fresh WiFi.begin().
  • Full flash erase. In the Arduino IDE choose Tools → Erase All Flash Before Sketch Upload → Enabled, upload once, then switch it back. This clears corrupted NVS data.
  • Power-cycle the router (not just the ESP32). Routers can hold a stale record of a device.
  • Try a different ESP32 board. Cheap clones vary, and a faulty antenna or regulator is rare but real.
  • Isolate the problem. Run the bare connection sketch with nothing else attached. If it connects reliably, add your peripherals one at a time.

Checklist You Can Print

  1. Print the disconnect reason code.
  2. Is the network 2.4 GHz, visible in a scan, with RSSI better than -75 dBm?
  3. Are SSID and password exactly right (try a phone hotspot to rule out code)?
  4. Is the router using WPA2, with no MAC filtering, no client limit and no isolation?
  5. Is the power supply solid (1A or more, short cable, capacitor)?
  6. Does it get an IP, DNS and gateway?
  7. For long runs: WiFi.setSleep(false) on mains power, reconnect logic and a restart fallback.

Frequently Asked Questions

Why does my ESP32 connect to my phone hotspot but not my router? Router security mode, band steering, MAC filtering or a WPA3-only setting. Use the checklist above.

Why does it say WL_NO_SSID_AVAIL? It cannot see the network. Usually the wrong name, a 5 GHz-only network or poor range.

How do I stop it disconnecting overnight? Disable modem sleep on mains power, add the reconnect strategy and check the power supply.

Should I use a static IP to fix disconnects? It can help with router DHCP quirks, but it does not fix signal or power problems. See the static IP guide.

How can I let users fix WiFi without re-flashing? Add a configuration portal with WiFiManager.

Image pending: Printed troubleshooting checklist next to an ESP32 and a laptop showing a stable connected Serial Monitor

Signal In

Built from what makers search for

The lookups piling up in SolderHub's search bar every day shape what we publish next — new component pages, board guides, and firmware notes, sent out as they go live.

By subscribing you agree to our Privacy Policy. Unsubscribe anytime.