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

Table 3-1 of the ESP32 datasheet: default configuration of the five strapping pins GPIO0, GPIO2, MTDI, MTDO, GPIO5
The five strapping pins and their idle levels, from the ESP32 Series Datasheet v5.3, page 22 (Espressif). Written out in the register’s bit order they spell 0x13.

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.

ESP32-DevKitC V4 schematic: the two-transistor auto-program circuit with its DTR/RTS truth table, and the IO0 and EN buttons with 0.1 µF capacitors C15 and C14
Two crops from Espressif’s ESP32-DevKitC V4 schematic (6 Dec 2017): the “Auto program” transistor pair with its truth table, and the BOOT (IO0) and EN buttons. Note C14: 0.1 µF on EN.

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

  1. 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.
  2. 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_reset on v4). That is the procedure the reporter of issue #949 settled on.
  3. 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.
  4. 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.
  5. 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 the set-flash-voltage 3.3V eFuse. GPIO15 low silences the ROM. The reporter of #949 found “another hardware was connected to the ESP32” was the whole problem.
  6. “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.”
  7. 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.
  8. 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

esptool: pip install esptool (official, cross-platform) · Flash Download Tool 3.9.11: Espressif’s Windows GUI, hosted here

Download Flash Download Tool 3.9.11 (Windows)

File: Flash_Download_Tool_3.9.11.zip · 25,943,693 bytes · SHA-256: c1fbf280aa04cd8fbe725bff74360fb0a7c83fbd49afcaf37f6c14a6575ea9bc · unmodified mirror of Espressif’s own build, see the Flash Download Tool guide for offsets and settings. Official page: espressif.com → Other Tools.

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

Sources