DEV Community

코딩나우(하늘아래)
코딩나우(하늘아래)

Posted on Originally published at coding-now.com

ESP32 upload errors decoded: 'Failed to connect', 'Wrong boot mode detected' and friends

ESP32 uploads fail in a handful of ways, and the error text already tells you where it stopped. Arduino IDE, PlatformIO and ESP-IDF all upload through esptool, so the messages are the same everywhere. The wording below is taken from the esptool source (v4.8.1 and current master).

The four stages

1. open the port        -> Could not open COM3, the port is busy or doesn't exist.
2. reset into download  -> Wrong boot mode detected (0x13)! The chip needs to be in download mode.
3. sync with the chip   -> No serial data received.
                           Download mode successfully detected, but getting no sync reply: The serial TX path seems to be down.
4. write flash          -> Invalid head of packet (0x..): Possible serial noise or corruption.
                           Serial data stream stopped: Possible serial noise or corruption.
Enter fullscreen mode Exit fullscreen mode

Everything starts with A fatal error occurred:, and connection-stage errors add Failed to connect to ESP32: (the chip name changes with the board).

Could not open COM3, the port is busy or doesn't exist

The line under it is the real cause:

(could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5))
Enter fullscreen mode Exit fullscreen mode

PermissionError(13, ...) means another program has the port open, like a terminal or a serial monitor in another IDE window. FileNotFoundError(2, ...) means there is no port with that name. Close whatever holds the port, unplug and replug the board with Device Manager open to spot the real port, install the USB chip driver (Silicon Labs for CP210x, WCH for CH340), and make sure the cable has data lines.

A detail from the source: esptool adds its Hint: line by matching the English text Access is denied. On a non-English Windows that text is localized, so the busy-port hint may not show up at all. On Linux, Permission denied means your user needs to be in dialout (or uucp).

No serial data received

The port opened, but after the reset not a single byte came back.

  1. Manual download mode: hold BOOT while Connecting... is printed. If that isn't enough, keep holding BOOT and tap EN. Let go once Writing at 0x... appears.
  2. Plug straight into the PC with a short data cable, no hub.
  3. Power: the esptool docs say the 3.3 V supply has to handle 200-300 mA peaks. Disconnect motors, LED strips and other hungry parts.
  4. Bare module on a USB-serial adapter: adapter TX to ESP32 RX, adapter RX to ESP32 TX, common ground.
  5. Lower the upload speed (see below).

Wrong boot mode detected (0x13)

Half good news: esptool read the boot log, so the serial link works. The chip just booted the app in flash instead of download mode. esptool decides this by looking for waiting for download in the boot log it reads right after the reset:

boot:0x13 (SPI_FAST_FLASH_BOOT)                       <- GPIO0 was HIGH at reset: normal boot
boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download                                  <- GPIO0 was LOW: download mode
Enter fullscreen mode Exit fullscreen mode
  • Hold BOOT during Connecting....
  • Remove anything wired to GPIO0 or GPIO2. GPIO0 held HIGH blocks download mode, and GPIO2 must be floating or LOW to enter it.
  • GPIO12 pulled HIGH selects 1.8 V flash voltage, which breaks boards with 3.3 V flash.
  • If every single upload needs BOOT, suspect the board's auto-reset timing or a USB hub before your code.

No sync reply: the serial TX path seems to be down

Download mode was detected, so the chip's output reaches the PC, but it never answers esptool. Only the PC-to-ESP32 direction is broken. With an adapter, check adapter TX to ESP32 RX (GPIO3, U0RXD). On a dev board this is rare, so try another board with the same cable and PC.

Invalid head of packet / Serial data stream stopped

The upload starts and dies partway. The esptool docs point at poor cables, pins shorting on a breadboard, and brownouts. Slow it down:

Tool Setting
Arduino IDE Tools > Upload Speed > 115200
PlatformIO upload_speed = 115200
ESP-IDF idf.py -p COM3 -b 115200 flash
esptool -b 115200 (the docs go as low as -b 9600 to diagnose)

Also keep stray wires off the flash pins (GPIO6-11 on the classic ESP32) and give high-current parts their own supply during uploads.

After a successful upload

If nothing runs, the chip is probably still in download mode, so press EN. On an ESP32-S3 or C3 flashed over native USB, that reset doesn't re-sample the strapping pins, and esptool's --after watchdog-reset handles it.


The full version with diagrams, plus the companion post on why the board resets whenever a serial monitor opens:

Which of these do you run into most?

Top comments (0)