$linuxjunkies
>

Flash Tasmota onto an ESP8266/ESP32 Device

Flash Tasmota firmware onto ESP8266/ESP32 devices from Linux using esptool.py, configure GPIO templates, connect to MQTT, and enable OTA updates.

AdvancedUbuntuDebianFedoraArch12 min readUpdated June 7, 2026

Before you start

  • Python 3.8 or newer installed on the Linux host
  • A 3.3 V USB-to-serial adapter or device with a built-in USB UART
  • An MQTT broker reachable on the local network (e.g., Mosquitto)
  • Physical access to the ESP device's serial pads or FLASH/RESET buttons

Tasmota is open-source firmware for ESP8266 and ESP32 microcontrollers — the chips powering countless cheap smart plugs, bulbs, and sensors. Replacing the factory firmware removes cloud dependencies and gives you local MQTT control, scripting, and OTA updates. Flashing from a Linux host is cleaner than Windows-based alternatives: esptool.py is well-maintained, the serial subsystem is stable, and you stay in your terminal the entire time.

What You Need

  • An ESP8266 or ESP32 device with an accessible serial interface (USB-to-serial adapter or built-in USB UART)
  • A 3.3 V USB-to-serial adapter (FTDI FT232R, CP2102, or CH340) if the board has no built-in USB
  • esptool.py installed on your Linux host
  • The correct Tasmota binary from tasmota.github.io
  • Access to a running MQTT broker (Mosquitto recommended)

Install esptool.py

esptool.py is a Python package. Install it in a virtual environment to avoid conflicts with system Python packages — this matters on any distro running Python 3.11+ where PEP 668 is enforced.

python3 -m venv ~/esptool-env
source ~/esptool-env/bin/activate
pip install esptool

On Debian/Ubuntu you can also use the system package, but it lags behind upstream:

sudo apt install esptool

On Fedora/RHEL:

sudo dnf install python3-esptool

On Arch:

sudo pacman -S esptool

Verify the install:

esptool.py version

Add Your User to the dialout Group

Serial ports live under /dev/ttyUSB* or /dev/ttyACM* and are owned by the dialout group (or uucp on Arch). Without group membership you will get a permission denied error even as a sudoer.

# Debian/Ubuntu/Fedora
sudo usermod -aG dialout $USER

# Arch
sudo usermod -aG uucp $USER

Log out and back in, or run newgrp dialout in the current shell to activate the change immediately. Confirm with groups.

Put the Device into Flash Mode

ESP devices must be held in bootloader mode during flashing. The exact method depends on your hardware:

  • Devices with a FLASH/BOOT button (NodeMCU, Wemos D1 Mini, most dev boards): hold FLASH/BOOT, press and release RESET, then release FLASH/BOOT.
  • Smart plugs and production hardware: you must identify and solder wires to the TX, RX, GND, and 3.3 V pads, then pull GPIO0 to GND before powering the board. Never connect 5 V — ESP chips are 3.3 V only.
  • ESP32-S2 and ESP32-S3: these appear as USB CDC devices and usually enter bootloader mode automatically when esptool.py drives DTR/RTS. No manual GPIO pull-down needed.

Identify the device node after plugging in:

ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null
# Typical output: /dev/ttyUSB0

Erase and Flash Tasmota

Download the Binary

For a standard ESP8266 device, download the main tasmota.bin. For ESP32 you need both the firmware image and the partition table. Check the Tasmota GitHub releases for the correct set. Sensor-specific builds (tasmota-sensors.bin, tasmota-display.bin) add drivers; use them only when you need the extra size budget.

wget https://github.com/arendst/Tasmota/releases/latest/download/tasmota.bin

Erase Flash

Always erase before flashing. Leftover factory data causes unpredictable Wi-Fi and RF behaviour.

esptool.py --port /dev/ttyUSB0 --baud 115200 erase_flash

Flash ESP8266

esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash \
  --flash_size detect \
  --flash_mode dout \
  0x0 tasmota.bin

--flash_mode dout is correct for the vast majority of ESP8266 modules. Some bare ESP-12 modules need dio; consult the datasheet if you get boot loops.

Flash ESP32

ESP32 requires four images written to specific offsets. Download the full release bundle for your variant (ESP32, ESP32-S2, ESP32-S3, ESP32-C3) from the Tasmota releases page, then:

esptool.py --port /dev/ttyUSB0 --baud 460800 \
  --chip esp32 write_flash \
  0x1000  bootloader_dout_40m.bin \
  0x8000  partitions.bin \
  0xe000  boot_app0.bin \
  0x10000 tasmota32.bin

The exact bootloader binary name varies between ESP32 chip variants. Check the bundle's README or the Tasmota flashing docs for your specific chip. On ESP32-S2/S3/C3 the bootloader offset is 0x0, not 0x1000.

Initial Wi-Fi and GPIO Configuration

After the flash completes, power-cycle the device. It boots into AP mode and broadcasts a network named tasmota-XXXXXX. Connect to it, navigate to http://192.168.4.1, and enter your Wi-Fi credentials. The device will reboot and join your network.

Assign a GPIO Template

Factory Tasmota knows nothing about which GPIO does what on your specific hardware. Templates encode pin assignments. Find your device on templates.blakadder.com, copy the JSON string, then in the Tasmota web UI go to Configuration → Configure Other, paste it into the Template field, tick Activate, and save.

For a custom or undocumented board, go to Configuration → Configure Module and assign each GPIO manually. Common assignments:

  • Relay1 — the GPIO driving a relay coil or LED
  • Button1 — a physical momentary switch
  • I2C SDA / I2C SCL — for BME280, SHT30, etc.

MQTT Integration

Go to Configuration → Configure MQTT. Fill in your broker's IP or hostname, port (default 1883), and credentials. Tasmota uses a topic hierarchy of %prefix%/%topic% where prefix is one of cmnd (commands), stat (status replies), or tele (telemetry). The device topic defaults to tasmota_XXXXXX; rename it to something meaningful like plug-kitchen.

Test from your Linux host with Mosquitto clients:

# Turn relay on
mosquitto_pub -h 192.168.1.10 -t 'cmnd/plug-kitchen/POWER' -m 'ON'

# Read current power state
mosquitto_sub -h 192.168.1.10 -t 'stat/plug-kitchen/#' -v

Tasmota publishes telemetry on a configurable interval (default 300 s). Adjust it in the console:

# Shorten telemetry to every 60 seconds
mosquitto_pub -h 192.168.1.10 -t 'cmnd/plug-kitchen/TelePeriod' -m '60'

OTA Updates

Tasmota supports two OTA methods. Both require the device to already be on Tasmota and reachable on the network.

Web UI OTA

Go to Firmware Upgrade in the web UI, enter the OTA URL (Tasmota publishes a release URL you can paste directly), and click Start Upgrade. The device fetches and verifies the image, then reboots.

MQTT-triggered OTA

mosquitto_pub -h 192.168.1.10 \
  -t 'cmnd/plug-kitchen/OtaUrl' \
  -m 'http://ota.tasmota.com/tasmota/release/tasmota.bin'

mosquitto_pub -h 192.168.1.10 \
  -t 'cmnd/plug-kitchen/Upgrade' \
  -m '1'

The device publishes progress to stat/plug-kitchen/UPGRADE. OTA over HTTP is fine on a trusted LAN; for WAN updates use HTTPS and a binary signed against the Tasmota release key.

Verification

After flashing and configuring, confirm everything is healthy:

# Ping the device
ping -c 3 plug-kitchen.local

# Query firmware info via MQTT
mosquitto_pub -h 192.168.1.10 -t 'cmnd/plug-kitchen/Status' -m '2'
mosquitto_sub -h 192.168.1.10 -t 'stat/plug-kitchen/STATUS2' -C 1 -v

The STATUS2 response contains firmware version, build date, and core version. Confirm they match the release you flashed.

Troubleshooting

  • esptool.py can't connect / timeout: The device is not in bootloader mode. Re-pull GPIO0 to GND before power-on. Check that no other process (ModemManager, brltty) has grabbed the serial port — disable or mask them: sudo systemctl mask ModemManager.
  • Wrong baud rate: Try 74880 to read the ROM boot message, which confirms the chip is alive. Then retry at 115200.
  • Boot loop after flash: Wrong flash mode. Re-flash with --flash_mode dio or qio depending on the module.
  • MQTT not connecting: Verify the broker allows the client ID. Tasmota generates a unique client ID; if your broker enforces ACLs, add it explicitly. Check mosquitto -v logs on the broker host.
  • OTA fails midway: The binary is too large for available flash. Use a minimal build (tasmota-lite.bin) or enable 1 MB layouts only if your chip actually has 1 MB. Most ESP8266 modules ship with 1–4 MB; read the chip ID output from esptool.py.
tested on:Ubuntu 24.04Fedora 40Arch 2024.05

Frequently asked questions

Can I flash Tasmota without soldering on a commercial smart plug?
Sometimes. Some older Sonoff and Tuya devices had exposed serial pads you could pogo-pin to. Many 2022+ devices use UART-locked chips or have switched to ESP32-based platforms with no easy serial access — check the Tasmota device compatibility list before buying.
What is the difference between tasmota.bin and tasmota32.bin?
tasmota.bin targets the ESP8266 architecture; tasmota32.bin is compiled for the ESP32 Xtensa core. They are not interchangeable. Additional variants exist for ESP32-S2, S3, and C3 which have different chip architectures and bootloader offsets.
How do I prevent accidental OTA from overwriting a working config?
Tasmota preserves the configuration partition across OTA updates by default. You can also disable OTA entirely via the console command SetOption78 1, or restrict MQTT ACLs on your broker to prevent unauthorized Upgrade commands.
Does Tasmota work with Home Assistant without an MQTT broker?
Yes, since Tasmota 9.1 it supports Home Assistant auto-discovery over MQTT. You still need an MQTT broker (Mosquitto add-on in HA is easiest), but you do not need to manually configure entities — discovery publishes them automatically.
esptool.py detects the chip but the flash fails with a MD5 mismatch. What is wrong?
Usually a weak or noisy power supply — 3.3 V must be stable under load during the write. Avoid powering the ESP from the USB adapter's 3.3 V pin; use a dedicated LDO or bench supply capable of at least 300 mA.

Related guides