OTA WLAN update can accidently delete /html folder

Author: JulianDGTVCreated Aug 21, 2026Updated Aug 21, 2026
Labelsbug

The Problem

Environment Release: v16.1.0 Commit: a1ccda2 Device: ESP32 running AI-on-the-edge-device / Watermeter

Description I tried the new OTA-based method to update the Wi-Fi configuration by uploading a ZIP file containing only a new wlan.ini.

The Wi-Fi configuration itself was updated successfully and the device connected to the new WLAN after reboot! Great!

However, during the OTA process the complete /html folder on the SD card was deleted.

As a result, after reboot the device only displayed the emergency error page with: "We have one or more critical errors: 0x00000010"

The normal Web UI was no longer available. The buttons for Log Viewer and OTA Update also did not work.

Steps to reproduce

Run AI-on-the-edge-device v16.1.0. Create a ZIP file containing only: wlan.ini Upload this ZIP using the OTA Update function. Let the OTA process finish and reboot the device. The new WLAN settings are applied successfully. After reboot, error 0x00000010 is shown because /html is missing.

Relevant log output... The OTA log showed: [OTA] Start update process (/sdcard/firmware/watermeter_wlan_update.zip) [OTA FILE] Files to be extracted: 1 [OTA] Files unzipped. [OTA] Renaming folder /sdcard/html to /sdcard/html_old... [OTA] Renaming folder /sdcard/html_tmp to /sdcard/html... [OTA] Deleting folder /sdcard/html_old...

The uploaded ZIP did not contain an html folder, so apparently no /sdcard/html_tmp was created.

Nevertheless, the existing /sdcard/html folder was first renamed to /sdcard/html_old and afterwards /sdcard/html_old was deleted.

On the next boot the log reported:

[ERR] [SDCARD] Folder/file check: Folder /html not found [ERR] [SDCARD] Folder/file check: File /html/index.html not found [ERR] [SDCARD] Folder/file check: File /html/ota.html not found [ERR] [SDCARD] Folder/file check: File /html/log.html not found [ERR] [SDCARD] Folder/file check: File /html/common.js not found [ERR] [SDCARD] Folder/file check: File /html/version.txt not found

Expected behavior When an OTA ZIP contains only wlan.ini, the existing /html folder should remain untouched.

Alternatively, the OTA updater should only replace /html if a valid html_tmp folder was actually extracted from the uploaded archive.

It would also be safer if /html_old were deleted only after verifying that the new /html folder exists and contains the required files.

Actual behavior The OTA updater removes the existing /html directory even though the uploaded ZIP contains no replacement HTML files.

This leaves the device without the normal Web UI.

Recovery The device itself and the existing configuration were still intact. The issue could be fixed by restoring the original html folder for v16.1.0 onto the SD card. After restoring the folder, the device worked normally again with the new WLAN configuration.

Possible fix Before performing: /html -> /html_old /html_tmp -> /html delete /html_old

the updater could check whether /html_tmp actually exists and contains the expected files.

If no HTML files are part of the OTA package, the /html replacement procedure should simply be skipped.

Version

Release: v16.1.0 (Commit: a1ccda2)

Logfile

bash
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] ==================== Start ======================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check started...
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check successful
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] PSRAM size: 8388608 byte (8MB / 64MBit)
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] Total heap: 4377151 byte
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [MAIN] Camera info: PID: 0x26, VER: 0x42, MIDL: 0x7f, MIDH: 0xa2
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] TimeServer not defined, using default: pool.ntp.org
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] Configuring NTP Client...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Time zone set to CET-1CEST,M3.5.0,M10.5.0/3
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] time zone: +0100 Delta to UTC: 3600 seconds
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] The local time is unknown, starting with 1970-01-01 01:00:03
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Once the NTP server provides a time, we will switch to that one
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] CPU frequency: 160 MHz
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check started...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check successful
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Tag: 'v16.1.0', Release: v16.1.0 (Commit: a1ccda2), Date/Time: 2026-01-11 22:38, Web UI: Release: v16.1.0 (Commit: a1ccda2)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Reset reason: Power-on event (or reset button)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] SSID: <OLD_SSID>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Password: XXXXXXXX
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] RSSIThreshold: 0
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] WLAN config loaded, init WIFI...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Automatic interface config --> Use DHCP service
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Set hostname to: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Init successful
[0d00h00m06s] 1970-01-01T01:00:06 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m08s] 1970-01-01T01:00:08 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m10s] 1970-01-01T01:00:11 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m13s] 1970-01-01T01:00:13 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m15s] 1970-01-01T01:00:15 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m18s] 1970-01-01T01:00:18 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m20s] 1970-01-01T01:00:20 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m23s] 1970-01-01T01:00:23 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] Device info: CPU cores: 2, Chip revision: 300
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] SD card info: Name: SC16G, Capacity: 15193MB, Free: 15166MB
[0d00h00m25s] 1970-01-01T01:00:25 <WRN> [WIFI] Disconnected (201, No AP)
[0d00h00m25s] 1970-01-01T01:00:25 <INF> [MAIN] Initialization completed successfully
[0d00h00m27s] 1970-01-01T01:00:27 <INF> [TFLITE] Trying to load the model. If it crashes here, it ist most likely due to a corrupted model!
[0d00h00m27s] 1970-01-01T01:00:27 <INF> [LOGFILE] Set log level to ERROR
[0d00h00m27s] 1970-01-01T01:00:27 <ERR> [MQTT IF] Init aborted! Config error (URI, MainTopic or ClientID missing)
[0d00h00m27s] 1970-01-01T01:00:28 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h00m54s] 1970-01-01T01:00:54 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h01m21s] 1970-01-01T01:01:21 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h01m48s] 1970-01-01T01:01:48 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h02m15s] 1970-01-01T01:02:15 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h02m41s] 1970-01-01T01:02:41 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h03m08s] 1970-01-01T01:03:08 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h03m35s] 1970-01-01T01:03:35 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h04m02s] 1970-01-01T01:04:02 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h04m28s] 1970-01-01T01:04:29 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h04m55s] 1970-01-01T01:04:55 <ERR> [WIFI] Disconnected, multiple reconnect attempts failed (201), retrying after 5s
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] ==================== Start ======================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check started...
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check successful
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] PSRAM size: 8388608 byte (8MB / 64MBit)
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] Total heap: 4377151 byte
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [MAIN] Camera info: PID: 0x26, VER: 0x42, MIDL: 0x7f, MIDH: 0xa2
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] TimeServer not defined, using default: pool.ntp.org
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] Configuring NTP Client...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Time zone set to CET-1CEST,M3.5.0,M10.5.0/3
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] time zone: +0100 Delta to UTC: 3600 seconds
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] The local time is unknown, starting with 1970-01-01 01:00:03
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Once the NTP server provides a time, we will switch to that one
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] CPU frequency: 160 MHz
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check started...
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [SDCARD] Folder/file check: Folder /html not found
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [SDCARD] Folder/file check: File /html/index.html not found
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [SDCARD] Folder/file check: File /html/ota.html not found
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [SDCARD] Folder/file check: File /html/log.html not found
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [SDCARD] Folder/file check: File /html/common.js not found
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [SDCARD] Folder/file check: File /html/version.txt not found
[0d00h00m03s] 1970-01-01T01:00:03 <ERR> [HELPER] New System Status: 0x00000010
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Tag: 'v16.1.0', Release: v16.1.0 (Commit: a1ccda2), Date/Time: 2026-01-11 22:38, Web UI: ?
[0d00h00m03s] 1970-01-01T01:00:03 <WRN> [MAIN] Failed to read file html/version.txt to parse Web UI version
[0d00h00m03s] 1970-01-01T01:00:03 <WRN> [MAIN] Web UI version (?) does not match firmware version (a1ccda2)
[0d00h00m03s] 1970-01-01T01:00:03 <WRN> [MAIN] Recommendation: Repeat installation using AI-on-the-edge-device__update__*.zip
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Reset reason: Power-on event (or reset button)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] SSID: <NEW_SSID>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Password: XXXXXXXX
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Hostname: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] WLAN config loaded, init WIFI...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Automatic interface config --> Use DHCP service
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Set hostname to: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Init successful
[0d00h00m06s] 1970-01-01T01:00:06 <INF> [WIFI] Connected to: <NEW_SSID>, RSSI: -52
[0d00h00m07s] 1970-01-01T01:00:07 <INF> [WIFI] Assigned IP: <LOCAL_IP>
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] Device info: CPU cores: 2, Chip revision: 300
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] SD card info: Name: SC16G, Capacity: 15193MB, Free: 15175MB
[0d00h00m25s] 1970-01-01T01:00:25 <ERR> [MAIN] Initialization failed. Flow task start aborted. Loading reduced web interface...
[0d00h00m25s] 1970-01-01T01:00:25 <ERR> [MAIN SERVER] We have a critical error, not serving main page!
[0d00h00m30s] 1970-01-01T01:00:30 <ERR> [MAIN SERVER] We have a critical error, not serving main page!
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] ==================== Start ======================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check started...
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check successful
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] PSRAM size: 8388608 byte (8MB / 64MBit)
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] Total heap: 4377151 byte
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [MAIN] Camera info: PID: 0x26, VER: 0x42, MIDL: 0x7f, MIDH: 0xa2
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] TimeServer not defined, using default: pool.ntp.org
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] Configuring NTP Client...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Time zone set to CET-1CEST,M3.5.0,M10.5.0/3
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] time zone: +0100 Delta to UTC: 3600 seconds
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] The local time is unknown, starting with 1970-01-01 01:00:03
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Once the NTP server provides a time, we will switch to that one
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] CPU frequency: 160 MHz
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check started...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check successful
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Tag: 'v16.1.0', Release: v16.1.0 (Commit: a1ccda2), Date/Time: 2026-01-11 22:38, Web UI: Release: v16.1.0 (Commit: a1ccda2)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Reset reason: Power-on event (or reset button)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] SSID: <NEW_SSID>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Password: XXXXXXXX
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Hostname: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] WLAN config loaded, init WIFI...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Automatic interface config --> Use DHCP service
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Set hostname to: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Init successful
[0d00h00m06s] 1970-01-01T01:00:06 <INF> [WIFI] Connected to: <NEW_SSID>, RSSI: -52
[0d00h00m07s] 1970-01-01T01:00:07 <INF> [WIFI] Assigned IP: <LOCAL_IP>
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] Device info: CPU cores: 2, Chip revision: 300
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] SD card info: Name: SC16G, Capacity: 15193MB, Free: 15175MB
[0d00h00m25s] 1970-01-01T01:00:25 <INF> [MAIN] Initialization completed successfully
[0d00h00m27s] 1970-01-01T01:00:27 <INF> [TFLITE] Trying to load the model. If it crashes here, it ist most likely due to a corrupted model!
[0d00h00m27s] 1970-01-01T01:00:27 <INF> [LOGFILE] Set log level to ERROR
[0d00h00m27s] 1970-01-01T01:00:28 <ERR> [MQTT IF] Init aborted! Config error (URI, MainTopic or ClientID missing)
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] ==================== Start ======================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [MAIN] =================================================
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check started...
[0d00h00m00s] 1970-01-01T00:00:00 <INF> [SDCARD] Basic R/W check successful
[0d00h00m00s] 1970-01-01T00:00:01 <INF> [MAIN] PSRAM size: 8388608 byte (8MB / 64MBit)
[0d00h00m00s] 1970-01-01T00:00:01 <INF> [MAIN] Total heap: 4377151 byte
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [MAIN] Camera info: PID: 0x26, VER: 0x42, MIDL: 0x7f, MIDH: 0xa2
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] TimeServer not defined, using default: pool.ntp.org
[0d00h00m03s] 1970-01-01T00:00:03 <INF> [SNTP] Configuring NTP Client...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Time zone set to CET-1CEST,M3.5.0,M10.5.0/3
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] time zone: +0100 Delta to UTC: 3600 seconds
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] The local time is unknown, starting with 1970-01-01 01:00:03
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SNTP] Once the NTP server provides a time, we will switch to that one
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] CPU frequency: 160 MHz
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check started...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [SDCARD] Folder/file presence check successful
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Tag: 'v16.1.0', Release: v16.1.0 (Commit: a1ccda2), Date/Time: 2026-01-11 22:38, Web UI: Release: v16.1.0 (Commit: a1ccda2)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] Reset reason: Power-on event (or reset button)
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] SSID: <NEW_SSID>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Password: XXXXXXXX
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WLANINI] Hostname: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [MAIN] WLAN config loaded, init WIFI...
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Automatic interface config --> Use DHCP service
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Set hostname to: <HOSTNAME>
[0d00h00m03s] 1970-01-01T01:00:03 <INF> [WIFI] Init successful
[0d00h00m06s] 1970-01-01T01:00:06 <INF> [WIFI] Connected to: <NEW_SSID>, RSSI: -55
[0d00h00m07s] 1970-01-01T01:00:07 <INF> [WIFI] Assigned IP: <LOCAL_IP>
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] Device info: CPU cores: 2, Chip revision: 300
[0d00h00m23s] 1970-01-01T01:00:23 <INF> [MAIN] SD card info: Name: SC16G, Capacity: 15193MB, Free: 15175MB
[0d00h00m25s] 1970-01-01T01:00:25 <INF> [MAIN] Initialization completed successfully
[0d00h00m28s] 1970-01-01T01:00:28 <INF> [TFLITE] Trying to load the model. If it crashes here, it ist most likely due to a corrupted model!
[0d00h00m28s] 1970-01-01T01:00:28 <INF> [LOGFILE] Set log level to ERROR
[0d00h00m28s] 1970-01-01T01:00:28 <ERR> [MQTT IF] Init aborted! Config error (URI, MainTopic or ClientID missing)

Expected Behavior

When an OTA ZIP contains only wlan.ini, the existing /html folder should remain untouched.

Alternatively, the OTA updater should only replace /html if a valid html_tmp folder was actually extracted from the uploaded archive.

It would also be safer if /html_old were deleted only after verifying that the new /html folder exists and contains the required files.

Screenshots

No response

Additional Context

No response

Source: jomjol/AI-on-the-edge-device