Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Flash offset · esptool

Fix “Image file at 0x1000 doesn't look like an image file”

esptool found no ESP image header at that address — usually the wrong offset for the chip (0x0 vs 0x1000) or a merged/MicroPython .bin flashed to the wrong place.

ESP32ESP32-S3ESP32-C3ESP32-C6ESP32-S2Updated 3 Nov 2026

Community draft — report a mistake

What you see

OutputOutput
esptool.py v4.8.1
Serial port COM9
Connecting...
Chip is ESP32-S3 (QFN56) (revision v0.2)
Stub running...
Configuring flash size...
Flash will be erased from 0x00001000 to 0x0017efff...
Warning: Image file at 0x1000 doesn't look like an image file, so not changing any flash settings.
Compressed 1564672 bytes to 1023745...
Wrote 1564672 bytes (1023745 compressed) at 0x00001000 in 13.1 seconds (effective 955.6 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Each ESP chip family looks for its second-stage bootloader at a fixed flash address: 0x1000 on the classic ESP32 and ESP32-S2, 0x0 on the newer S3, C3 and C6. esptool checks for an image header at that address so it can patch the flash settings.

This warning means the header was not where it should be. The write itself finishes, but the chip will not find a bootloader. It is almost always the wrong offset for the chip, or a merged file written above 0x0.

Quick fix — try in order

  1. 1

    Use the right start address for your chip

    The bootloader (or a merged image) goes at 0x1000 on ESP32 and ESP32-S2, but at 0x0 on ESP32-S3, C3, C6 and H2. Flashing an S3 image at 0x1000 gives this warning and a board that never boots.

  2. 2

    MicroPython: copy the address from the download page

    micropython.org lists the exact command per chip. For ESP32-S3 and C3 firmware it is write_flash 0 firmware.bin; for classic ESP32 it is write_flash 0x1000 firmware.bin.

  3. 3

    Merged/factory .bin goes at 0x0

    A file named *.merged.bin or *-factory.bin contains bootloader, partition table and app together. Write it at 0x0 on every chip.

  4. 4

    Erase first, then flash once more

    Run esptool.py erase_flash, then flash at the correct address. Leftovers from a wrong-offset write can keep the old partition table around.

Why it happens

Why only a warning and not an error?

esptool can flash any data anywhere. It only uses the header at the bootloader address to patch flash mode and size. When there is no header there, it skips the patch and writes the bytes anyway — so the upload “succeeds” but the board will not boot.

What happens on the board?

The ROM looks for a bootloader at its fixed address, finds the wrong bytes and prints “invalid header: 0xffffffff” or similar in a loop. See invalid header.

Board-specific notes

ESP32-S3 / C3 / C6: Bootloader at 0x0, partitions at 0x8000, app at 0x10000.

ESP32 / ESP32-S2: Bootloader at 0x1000, partitions at 0x8000, app at 0x10000.

↑↓ to move · Enter to open