How do I fix “Failed to connect to ESP32: Timed out waiting for packet header”?

This one is almost always bootloader timing: your PC is talking to the USB serial chip, but the ESP32 never switched into upload mode when esptool tried to connect.

Quick fixes (90% of the time)

  1. Use a real data USB cable. If you're not 100% sure it's data-capable, swap it.
  2. Tools → Port: pick the port that appears when you plug the board in.
  3. Close Serial Monitor (and any other app using the port).
  4. Try a different USB port (skip hubs/docks for now).

Manual bootloader mode (most reliable)

Do this exactly once, slowly. It feels “too simple,” but it's the fix on a lot of boards.

  1. Click Upload in Arduino IDE.
  2. When you see Connecting..., press and hold BOOT.
  3. When the upload starts (progress shows), release BOOT.

If your board has EN/RST, tapping it right before Upload can help the timing.

The sneaky hardware stuff that breaks boot

  • Disconnect anything wired to GPIO0, GPIO2, GPIO12, GPIO15 while you troubleshoot. Strapping pins can block boot if they're pulled the wrong way at reset.
  • Don't power the board from a flaky 5V rail while uploading. Use USB only for the first upload.
  • If you're using a breadboard setup, reseat the ESP32 and check you're not shorting pins.

If it still won't connect

  • Try a lower upload speed. Tools → Upload Speed → pick something lower (like 115200).
  • Driver check: many boards use CP2102/CH340/CH9102. If the port is flaky or disappears, fix drivers first.
  • Try another computer once, just to separate “board problem” from “PC problem.”
Bottom line

“Timed out waiting for packet header” usually means the ESP32 didn't enter bootloader mode. Start with cable + port, then use the BOOT button method during “Connecting…”.

Related: What does “Failed to connect to ESP32” mean? · Why won't my board show up in COM ports? · How do I select the correct board and port?