Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode. means esptool heard the chip boot, read its strapping pins, and found GPIO0 high: the board was never reset into the ROM bootloader. The number is not an error code. It is the raw GPIO_STRAP register, one bit per strapping pin, and once you can read it the fault is usually obvious. Below: the bit map, every value you will see on an ESP32 and what the ROM does with it, and the causes in the order worth checking.
What esptool actually checks before it says “wrong boot mode”
The logic is in esptool/loader.py, function _connect_attempt(). After toggling DTR and RTS, esptool reads whatever the ROM printed and runs one regular expression over it: boot:(0x[0-9a-fA-F]+)(.*waiting for download)?. It then tries to sync five times. The three messages you can get map to three different faults:
| Message | What esptool saw | Where the fault is |
Wrong boot mode detected (0xNN)! The chip needs to be in download mode. |
A boot log with boot:0xNN, but no “waiting for download” and no sync reply |
The chip is alive and talking; it was not reset with GPIO0 low. Auto-reset circuit, driver timing, or something holding a strapping pin |
Download mode successfully detected, but getting no sync reply: The serial TX path seems to be down. |
“waiting for download” in the log, no sync reply | The chip’s RX line: the PC’s TX never reaches the chip (crossed wires, unsoldered pad, wrong pin) |
Failed to connect to ESP32: No serial data received. |
Nothing at all on the serial port | Wrong COM port, no power, chip’s TX line, or boot log silenced (GPIO15 low) |
The number, bit by bit
ESP-IDF’s gpio_reg.h for the ESP32 describes GPIO_STRAPPING as {10'b0, MTDI, GPIO0, GPIO2, GPIO4, MTDO, GPIO5}. So the six low bits of the value the ROM prints are, from bit 5 down to bit 0: MTDI (GPIO12), GPIO0, GPIO2, GPIO4, MTDO (GPIO15), GPIO5. Table 3-1 of the ESP32 datasheet gives the defaults with nothing connected: GPIO0 pull-up (1), GPIO2 pull-down (0), MTDI pull-down (0), MTDO pull-up (1), GPIO5 pull-up (1). In the register’s bit order that is 0 1 0 0 1 1, which is 0x13. Pull GPIO0 low and it becomes 0 0 0 0 1 1, 0x3. One bit, worth 0x10, separates “running my sketch” from “ready to flash”.

The ROM decides the boot path from those bits using the macros in ESP-IDF’s soc/esp32/include/soc/boot_mode.h: bit 4 set (GPIO0 high) is IS_1XXXX, SPI flash boot; bits 4 and 3 both clear is IS_00XXX, download boot; GPIO0 low with GPIO2 high and GPIO4 low is IS_010XX, “HSPI boot”. The table below is every value a classic ESP32 can print and what to do about it.
| boot: | MTDI · GPIO0 · GPIO2 · GPIO4 · MTDO · GPIO5 | ROM prints | Meaning | Do this |
| 0x13 | 0 1 0 0 1 1 | SPI_FAST_FLASH_BOOT | Board defaults. Normal boot; GPIO0 never went low while EN rose | Auto-reset failed: see causes 1–4 |
| 0x1b | 0 1 1 0 1 1 | SPI_FAST_FLASH_BOOT | GPIO2 is held high. Boots fine, but with GPIO0 low it turns into 0xb and cannot enter download | Find what pulls GPIO2 high (SD card DAT0, LED, pull-up) |
| 0x17 | 0 1 0 1 1 1 | SPI_FAST_FLASH_BOOT | GPIO4 high. Harmless; still not in download mode | Same as 0x13 |
| 0x12 | 0 1 0 0 1 0 | SPI_FAST_FLASH_BOOT | GPIO5 low. Only changes SDIO-slave timing; still not in download mode (esptool issue #925) | Same as 0x13 |
| 0x33 | 1 1 0 0 1 1 | SPI_FAST_FLASH_BOOT, then flash read err, 1000 |
MTDI/GPIO12 high at reset: VDD_SDIO switches to 1.8 V and a 3.3 V flash browns out | Free GPIO12 at boot, or burn the eFuse with espefuse set-flash-voltage 3.3V (irreversible) |
| 0x3 | 0 0 0 0 1 1 | DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2) + waiting for download |
Correct download mode | If flashing still fails: TX path, power, baud (causes 6–7) |
| 0x0, 0x1, 0x2 | 0 0 0 0 x x | DOWNLOAD_BOOT(… FEI_FEO / FEI_REO / REI_FEO V2) | Download mode too. The two low bits only set SDIO-slave edge timing | Fine for flashing |
| 0xb | 0 0 1 0 1 1 | HSPI_FLASH_BOOT, then flash read err, 1000 |
GPIO0 low and GPIO2 high: the ROM looks for flash on the HSPI pins and finds nothing | Release GPIO2; on an ESP32-CAM, pull the SD card (arduino-esp32 #6164) |
| 0xc, 0xd, 0xe, 0xf | 0 0 1 1 x x | Legacy SPI boot / SDIO-slave download V1.1 / ATE mode / diagnostic + UART0 download (names from boot_mode.h) |
GPIO0 low with GPIO2 and GPIO4 high; the two low bits pick which of the four | Unsupported; free GPIO2 and GPIO4 |
| any, MTDO = 0 | x x x x 0 x | nothing at all | GPIO15 low silences the ROM’s boot messages (bit 1 is ETS_IS_PRINT_BOOT) |
esptool cannot read the number; free GPIO15 or read the pins with a meter |
The rule worth memorising: any value with the 0x10 bit set means GPIO0 was high when EN rose, and the chip is not in download mode no matter what else you change. Values 0x0 to 0x3 are download mode. Anything from 0x8 to 0xf is GPIO0 low but GPIO2 high, and the ROM goes somewhere you do not want.
How the auto-reset works, and why 0.1 µF on EN is not enough
esptool does not press buttons; it wiggles two modem-control lines of the USB-to-serial chip. The sequence, from classic_bootloader_reset() in Espressif’s esp_pylib/serial_reset.py: DTR high, RTS low (EN low, chip in reset), wait 0.1 s, DTR low (IO0 low), RTS high (EN up, chip runs), wait 0.05 s, DTR high. On the DevKitC those two lines drive a pair of SS8050 transistors whose truth table is printed on the schematic: DTR 1 / RTS 0 pulls EN low, DTR 0 / RTS 1 pulls IO0 low, and both together leave the chip alone.

The catch is timing. Table 3-2 of the datasheet gives the strapping hold time as 1 ms after CHIP_PU goes high, so IO0 must already be low when EN rises. The serial_reset docstring admits the classic sequence “can briefly glitch through invalid (DTR, RTS) pairs” because pyserial writes the two lines one at a time; a driver that delays one write lets EN come up before IO0 is down. A capacitor on EN slows that edge so IO0 wins the race. The esptool documentation calls a capacitor “in the 1uF-10uF range” on EN “necessary for the reset circuitry to work reliably”. The DevKitC V4 schematic shows 0.1 µF there (C14 at the EN button, plus C9 next to the module), a tenth of the minimum.
That gap is real. In esptool issue #1050 (January 2025) an official ESP32-DEVKITC-VE that flashed “in 99.9% of the cases” with esptool 3.0 failed with Wrong boot mode detected (0x13) on 4.8.1. An Espressif engineer explained that an old longer-wait workaround for revision 0 silicon had been removed and asked the reporter to put 10 µF between EN and GND. Soldered on, it worked first time; the software alternative, custom_reset_sequence = D0|R1|W1.3|D1|R0|W0.5|D0 in esptool.cfg, worked “2 out of 10”. In issue #706, the Windows 11 thread with 60 comments, a user with a scope saw “RTS and DTR went up at the exact same time”; 2.2 µF fixed it, and so did Silicon Labs’ older CP210x VCP driver 6.7.0.0 where 6.7.6.2130 failed.
Causes, in the order to check
- Read the number first. 0x10 bit set (0x13, 0x1b, 0x17, 0x12): the reset into download mode did not happen; steps 2 to 4. 0xb or 0x33: a strapping pin is being pulled; step 5. 0x3 with “TX path seems to be down”: step 6.
- Reset by hand, in the right order. Hold BOOT, tap EN/RST, release BOOT only after esptool starts printing
Connecting..... Pressing BOOT after the reset does nothing; the latches closed 1 ms after EN rose. Stop esptool from undoing your reset:esptool --before no-reset --connect-attempts 15 flash-id(v5 spelling;no_reseton v4). That is the procedure the reporter of issue #949 settled on. - Add the capacitor. 1 µF to 10 µF, EN to GND, on any board with the two-transistor circuit and only 0.1 µF. It is the one fix that survives driver updates.
- Driver and OS. Windows 11 with CP210x: the 6.7.0.0 VCP package or the capacitor (issue #706). macOS through USB-C hubs and adapters: issue #712. Linux asserting RTS on an idle port:
sudo stty -F /dev/ttyUSB0 -hupcl, from the esptool docs. - Something on GPIO2, GPIO12 or GPIO15. GPIO2 high with BOOT pressed gives 0xb and
flash read err, 1000: on the AI-Thinker ESP32-CAM the SD card’s DAT0 sits on GPIO2, so flashing works with the card out and loops with it in (arduino-esp32 #6164). GPIO12 high gives 0x33 and the same read error at 1.8 V; free the pin or burn theset-flash-voltage 3.3VeFuse. GPIO15 low silences the ROM. The reporter of #949 found “another hardware was connected to the ESP32” was the whole problem. - “The serial TX path seems to be down”. The chip entered download mode and said so; your bytes are not arriving. TX and RX crossed, a lifted pad, a bridge chip with a bad joint. In arduino-esp32 #11034 a custom WROOM-32E board gave 0x13 until the CP2104 was reflowed a second time: “It really was an issue with the RX being not properly connected.”
- Power and cable. The esptool troubleshooting page is blunt: the 3.3 V output of FT232R adapters and Arduino boards “do not supply sufficient current to power an ESP chip”. A chip resetting mid-transfer shows up as
Invalid head of packet; in issue #983 the ESP-ROM banner was visible inside the hex dump. Test at-b 9600, then change the cable. - Boards with no USB (bare WROOM, ESP32-CAM on an FTDI): no auto-reset circuit, so step 2 applies every time, and the module needs its own supply, not the adapter’s regulator.
ESP32-S3 and ESP32-C3: different numbers, same idea
The newer chips print a 4-bit value and their boot_mode.h macros use bit 3 as the boot pin: IS_1XXX(v) (((v)&0x08)==0x08) is SPI boot. A running ESP32-S3 prints boot:0x8 (SPI_FAST_FLASH_BOOT) and in download mode boot:0x0 (DOWNLOAD(USB/UART0)); an ESP32-C3 prints boot:0xc running and boot:0x5 (DOWNLOAD(USB/UART0/1)) in download (arduino-esp32 #6762 and #7190, esptool #983). On the C3, GPIO8 must stay high: the docs call GPIO8 = 0 with GPIO9 = 0 “invalid”, which is the Wrong boot mode detected (0x1) of esptool #765, where both pins were wired as inputs. Through the chip’s own USB-Serial/JTAG port there are no DTR/RTS wires; esptool resets through the USB peripheral, and if the application has broken USB, hold BOOT while plugging the cable in.
⬇ The tools this page refers to
Download Flash Download Tool 3.9.11 (Windows)
The GUI speaks the same ROM protocol as esptool and fails the same way, with the number hidden. Open a serial terminal at 115200 baud, press EN, and read the boot: line yourself.
FAQ
Is 0x13 a sign the chip is damaged? No. 0x13 is the healthy default of a board running normally. The chip answered; it was simply not reset with GPIO0 low. A dead chip prints nothing.
Why does the same board flash on Windows 10 and fail on Windows 11? Because success depends on how fast the driver turns DTR and RTS around, and that changed with the CP210x driver (issue #706). Boards with 1 µF to 10 µF on EN never noticed; boards with 0.1 µF did.
I held BOOT and still got 0x13. You pressed it after the reset, or let go before esptool connected. BOOT must be down before EN rises and stay down until the dots stop; use --before no-reset so esptool’s own reset does not undo yours.
Related guides
- esptool step by step: v5 command names and the bootloader offset per chip
- ESP32 Flash Download Tool 3.9.11: the Windows GUI, offsets and SPI mode
- NodeMCU PyFlasher 5.1.0: the flash mode each ESP8266 and ESP32 board needs
- CP2102 driver and CH340 driver: the two bridge chips on most ESP32 dev boards
- Arduino IDE 2: port not showing: when the problem is one step earlier
Sources
- Espressif, esptool, esptool/loader.py,
_connect_attempt(): the boot-log regex and the three error strings - Espressif, esp-pylib, esp_pylib/serial_reset.py:
classic_bootloader_reset()timings and the “invalid pairs” note - Espressif, ESP-IDF, soc/esp32/register/soc/gpio_reg.h:
GPIO_STRAPPINGbit order - Espressif, ESP-IDF, soc/esp32/include/soc/boot_mode.h (and the esp32s3 / esp32c3 versions): the boot-mode macros
- Espressif, ESP32 Series Datasheet v5.3, section 3 “Boot Configurations”, Tables 3-1 and 3-2
- Espressif, ESP32-DevKitC V4 schematic (6 Dec 2017): auto-program circuit, C9, C14, C15
- esptool docs: Boot Mode Selection (ESP32), Boot Mode Selection (ESP32-C3), Troubleshooting, Configuration File (custom reset sequences), espefuse set-flash-voltage
- esptool issues #706 (Windows 11, CP210x), #712 (macOS USB-C adapters), #1050 (official DevKitC-VE, 10 µF), #925 (0x12), #949 (manual procedure on Mac), #765 (C3, 0x1), #983 (C3 brown-out mid-flash)
- arduino-esp32 issues #6164 (ESP32-CAM, SD card, 0xb), #11034 (TX path, CP2104), #6762 (S3 boot codes), #7190 (C3 boot codes)
