Bitaxe – SPIFFS www Partition Missing / Web UI 404
Warning — Should be addressed soon
Symptoms
- `http://<miner-ip>/` returns a completely blank page with `Content-Length: 0`, no HTML, no error
- Browser shows `404 Not Found` or `ESP_ERR_NOT_FOUND` as a tiny plaintext line — branded AxeOS React shell never appears
- `curl -v http://<miner-ip>/` returns `HTTP/1.1 404 Not Found` from the ESP32's `esp_http_server`, not from the browser
- Serial console at `115200` baud shows `E (XXX) SPIFFS: mount failed` or `Failed to mount or format filesystem`
- Serial line `Partition '/spiffs' not found` or `Partition with label 'storage' not found`
- `httpd: file_uri_handler: failed to open file <path>` repeated for every static asset request
- OLED still shows live hashrate, IP, and worker — firmware is healthy
- Pool dashboard confirms shares submitted in the last 10 minutes
- Started immediately after a partial OTA update that crashed mid-`www.bin` transfer (browser tab closed, WiFi dropped, miner power-cycled)
- Started after flashing only `esp-miner.bin` via `esptool.py` without flashing `www.bin` to its companion offset
- Started after flashing a custom partition table that omitted the `spiffs` entry or sized it incorrectly
- `curl -v http://<miner-ip>/api/system/info` returns valid JSON — API endpoints work, only static UI is gone
- Reflashing `esp-miner.bin` alone does not fix it; SPIFFS partition still reads as empty
Step-by-Step Fix
Confirm the miner is alive before chasing the UI. Check the OLED: hashrate nonzero, IP shown, worker name visible. Cross-check at your pool — `solo.ckpool.org`, `public-pool.io`, Ocean, or Braiins — for a share submitted within the last 10 minutes. The signature of this whole page is `miner fine, web UI gone`. If the miner itself is down, you are on the wrong page; back out to the Bitaxe Not Hashing or ESP32 Crash Loop guides instead. Don't burn cycles flashing partitions on a miner whose actual problem is somewhere else entirely.
Hard-refresh the browser with `Ctrl`+`Shift`+`R` on Windows/Linux or `Cmd`+`Shift`+`R` on macOS, then retry the miner's URL in a private window or a different browser. A blank dashboard *can* be a stale browser cache from before an OTA — clear browser-side first. If the page is genuinely served as `404 Not Found` or returns zero bytes after a hard refresh in incognito, you are in `www` partition territory. If it loads fine after the refresh, you were chasing a browser cache, not a partition issue.
Cold-boot the Bitaxe for 30 full seconds. Pull the barrel jack or XT30 connector, wait the full 30 seconds for capacitors to drain and SRAM to fully clear, plug back in. Wait for the OLED to show hashing. Retry the dashboard URL. A genuine SPIFFS mount failure does occasionally recover on a clean boot if the cause was a transient flash-read glitch — rare, but free to try, and rules out one more cause before reaching for a USB-C cable and the web flasher.
Hit every static URL the React shell loads — `http://<miner-ip>/`, `/index.html`, `/favicon.ico`, `/manifest.json` — plus the API. If every static URL returns blank or `404` but `http://<miner-ip>/api/system/info` returns valid JSON with `hashRate`, `temp`, and `version`, you have unambiguously confirmed the firmware is healthy and only the SPIFFS `www` partition is empty. That is the diagnostic signature this page exists to fix. Move to Tier 2.
Get a USB-C *data* cable. Charge-only cables silently fail to enumerate the ESP32-S3 over USB and look identical to a dead board. The single most common false-brick on the D-Central bench is a customer who tried three cables from a drawer, all charge-only. A real data cable will show `USB Serial Device` (Windows), `cu.usbmodem*` (macOS), or `/dev/ttyACM0` (Linux) the moment you plug in.
Open the official Bitaxe Web Flasher at `https://bitaxeorg.github.io/bitaxe-web-flasher/` in Chrome or Edge — Firefox and Safari do not implement the Web Serial API the flasher needs. Plug the Bitaxe in over USB-C, click `Connect`, pick the COM / `tty` port that just appeared. If the flasher cannot see the chip even after a known-good cable swap, hold the `BOOT` button on the board while plugging in to force ESP32-S3 ROM bootloader mode, which the flasher always recognises.
Pick the correct factory image for your chip variant. Mismatched `.bin` is one of the few ways a recovery flash can make things worse. Mapping: Bitaxe Ultra = `BM1366`, Bitaxe Supra = `BM1368`, Bitaxe Hex = 6× `BM1368` (uses the multichip fork at `https://github.com/bitaxeorg/ESP-Miner-multichip`), Bitaxe Gamma and GT = `BM1370`. Verify against the chip silkscreen on your board if there's any doubt. Wrong-chip firmware bricks the ASIC driver path; right-chip firmware restores everything.
Run a full factory flash (not OTA-app-only). The factory bundle writes bootloader + partition table + `esp-miner.bin` + `www.bin` in a single sweep — exactly what restores a missing or corrupt SPIFFS partition without you having to think about offsets. The flasher erases first, then writes, then verifies. Watch for `Hash of data verified` lines. Total time 60–120 seconds depending on flash size and USB throughput. After completion the miner boots into AP mode for setup.
Reconfigure from the AP-mode wizard. A factory flash erases NVS — your stored WiFi credentials, pool URL, worker name, and ASIC calibration are wiped. After first boot, the Bitaxe broadcasts a `Bitaxe_xxxx` SSID. Connect from your phone, browse to `http://192.168.4.1/`, walk the setup wizard: pool URL, worker name (your BTC address for solo mining), frequency, voltage. Save. The miner reboots into station mode with a fresh, working `www` partition serving the dashboard.
Install `esptool.py` and `gen_esp32part.py` if you don't already have them. `pip install esptool` on any Python 3.9+ install. `gen_esp32part.py` ships with ESP-IDF or stand-alone from the Espressif GitHub. These two tools are the truth-source — the web flasher hides what's happening at the flash-block level; the CLI shows you everything. Mining Hackers run CLI; everyone else runs the web flasher and gets the same result 95% of the time.
Dump the existing partition table. `esptool.py --chip esp32s3 --port <port> read_flash 0x8000 0xC00 part_dump.bin`, then `gen_esp32part.py part_dump.bin partitions.csv` to decode. Inspect the output for a row of type `data, spiffs` (or `data, littlefs` on some forks) — note its offset and size. If the row is missing, your partition table doesn't declare a `www` partition, which is why no amount of reflashing `www.bin` to a guessed offset will help. Move to the full-erase recovery (Step 13).
Flash `www.bin` only at the correct offset. Once you've confirmed the partition table has a valid `spiffs` / `littlefs` entry: download the matching `www.bin` for your AxeOS version from `https://github.com/bitaxeorg/ESP-Miner/releases` and run `esptool.py --chip esp32s3 --port <port> --baud 460800 write_flash <offset> www.bin`. The canonical offset on the standard 8 MB layout is `0x310000`, but always read it out of the dumped partition table — never assume. Wait for `Hash of data verified`, reset, retry the dashboard.
Full `erase_flash` + factory bundle if Step 12 doesn't recover. `esptool.py --chip esp32s3 erase_flash` wipes everything from `0x0` to end-of-chip. Then either run the web flasher's factory image, or hand-flash the four binaries from the matching factory release: `bootloader.bin` at `0x0`, `partition-table.bin` at `0x8000`, `esp-miner.bin` at `0x10000`, `www.bin` at the offset declared by that release's `partitions.csv`. One factory bundle, all four files from the same release, no mixing versions across binaries — that's the rule that prevents 90% of self-inflicted re-bricks.
Verify SPIFFS mount on the next boot via serial. After reflashing, leave USB-C connected and watch the boot log at `115200` baud. You want to see `SPIFFS_check successful`, `esp_spiffs_init: spiffs partition mounted`, and `httpd_start: server started successfully` with no error lines. If you still see `SPIFFS: mount failed` after a clean factory flash, the underlying flash chip has worn or damaged sectors at the SPIFFS partition's offset — that's a hardware fault, not a software fix. Move to Tier 4.
Pin your AxeOS version to a stable release. After recovery, do not auto-update on a miner that's earning. Pick the latest stable from `https://github.com/bitaxeorg/ESP-Miner/releases`, note the version, and only update over USB-C — never over OTA on weak WiFi. Mid-OTA brownouts during the `www.bin` chunk are the single biggest preventable cause of this whole failure mode. If you must OTA, do it on wired Ethernet (USB-Ethernet adapter clipped to the bench setup), or hotspot the miner directly off your phone for the duration.
Stop DIY when (a) you've run a full erase + factory flash twice with the correct chip-variant `.bin` and SPIFFS still doesn't mount, (b) the serial log shows repeated `spi_flash_read: timeout` or `Flash erase failed` from a known-good 5 V / 5 A PSU and a known-good USB-C data cable, (c) the ESP32-S3 won't enumerate over USB-C on any cable / laptop / OS combination even with `BOOT` held during plug-in, or (d) there's visible burn damage, lifted traces, or burnt-component smell near the USB-C port, ESP32 module, or flash chip. At that point you're dealing with damaged silicon, not corrupt software — bench territory.
What D-Central does at the bench: connect via the on-board UART pads if USB-C is dead, dump the SPI flash to a file with an external programmer (CH341A or T56 against the populated SOP-8 / WSON-8 footprint), inspect the partition table offline, identify whether the failure is partition-corruption, app-corruption, or hardware-level flash damage. If it's flash damage we reball the SPI flash chip onto a fresh die. If it's the ESP32-S3 module itself we swap the module — Bitaxe boards expose ESP32-S3 as a standard module footprint, which is exactly why open-source hardware is repairable in ways closed-source ASIC controllers aren't.
Ship safely. Anti-static bag, double-box with at least 3 cm of foam on every side, and a note inside that includes Bitaxe variant (Supra / Ultra / Gamma / GT / Hex), last known working AxeOS version, what you tried (factory flash, partial reflash, `erase_flash`), what the serial log showed, and a return contact. Saves us 30–60 minutes of diagnostic time which directly saves you on the repair quote. D-Central pioneered the Bitaxe Mesh Stand and stocks every Bitaxe variant — we know this hardware better than almost anyone in the Western hemisphere.
When to Seek Professional Repair
If the steps above do not resolve the issue, or if you are not comfortable performing these repairs yourself, professional service is recommended. Attempting advanced repairs without proper equipment can cause further damage.
Related Error Codes
Still Having Issues?
Our team of Bitcoin Mining Hackers has been repairing ASIC miners since 2016. We have seen it all and fixed it all. Get a professional diagnosis.
