Wi-Fi: a panic at join, SNTP started twice ("Operating mode must not be set while SNTP client is running") #46

Closed
opened 2026-10-06 07:03:40 +00:00 by twisla · 1 comment
Owner

What happens

Now and then the firmware panics about nine seconds after boot, when Wi-Fi joins:

assert failed: sntp_setoperatingmode /IDF/components/lwip/lwip/src/apps/sntp/sntp.c:748
(Operating mode must not be set while SNTP client is running)
task tiT

Seen once, on 2026-10-06, on the first boot of a new Debug Build (v0.8.1-3-gb7aed8e+debug) during F1's testing. The build was on Probation, so Rollback put the previous one back by itself. About a dozen other boots that day didn't hit it.

Why

Two things, both there since v0.7.0 (#7):

  1. The DNS and NTP setup ran twice at every join, in the same pass. WifiService::tick() calls startNtp(), which stamps serversCheckedMs_ from millis(); a few lines on, the "check now and then" timer computes nowMs - serversCheckedMs_ with the pass's own, older nowMs. The unsigned difference underflows and the check runs again at once.
  2. applyServers() asked esp_sntp_enabled() whether to start SNTP. esp_sntp_setoperatingmode() and esp_sntp_init() only queue their work for the network task (tcpip_callback). When the second run looks before the first has been carried out, it queues a second start, and lwIP asserts when that one is processed.

The network task has a high priority and its own core, so the window is a few microseconds; that's why it's rare.

Fix

Commit e14eb30, on f1: the service remembers that it started SNTP instead of asking, and the timer compares signed. Ships in v0.9.0.

Left to look at

The same shape of comparison (nowMs - somethingMs_ >= ..., where the stamp may come from millis() later in the same pass) exists in other places. The ones in the Apps only cause an extra redraw; none of the others was found to stamp from millis(), but they weren't all traced.

Related

#7 (fixed IPv4, DNS and NTP), where the code came in.

## What happens Now and then the firmware panics about nine seconds after boot, when Wi-Fi joins: ``` assert failed: sntp_setoperatingmode /IDF/components/lwip/lwip/src/apps/sntp/sntp.c:748 (Operating mode must not be set while SNTP client is running) task tiT ``` Seen once, on 2026-10-06, on the first boot of a new Debug Build (`v0.8.1-3-gb7aed8e+debug`) during F1's testing. The build was on Probation, so Rollback put the previous one back by itself. About a dozen other boots that day didn't hit it. ## Why Two things, both there since v0.7.0 (#7): 1. **The DNS and NTP setup ran twice at every join, in the same pass.** `WifiService::tick()` calls `startNtp()`, which stamps `serversCheckedMs_` from `millis()`; a few lines on, the "check now and then" timer computes `nowMs - serversCheckedMs_` with the pass's own, older `nowMs`. The unsigned difference underflows and the check runs again at once. 2. **`applyServers()` asked `esp_sntp_enabled()` whether to start SNTP.** `esp_sntp_setoperatingmode()` and `esp_sntp_init()` only queue their work for the network task (`tcpip_callback`). When the second run looks before the first has been carried out, it queues a second start, and lwIP asserts when that one is processed. The network task has a high priority and its own core, so the window is a few microseconds; that's why it's rare. ## Fix Commit e14eb30, on `f1`: the service remembers that it started SNTP instead of asking, and the timer compares signed. Ships in v0.9.0. ## Left to look at The same shape of comparison (`nowMs - somethingMs_ >= ...`, where the stamp may come from `millis()` later in the same pass) exists in other places. The ones in the Apps only cause an extra redraw; none of the others was found to stamp from `millis()`, but they weren't all traced. ## Related #7 (fixed IPv4, DNS and NTP), where the code came in.
twisla added the
kind
bug
area/wifi
priority
high
labels 2026-10-06 07:03:40 +00:00
Author
Owner

The fix (e14eb30) is on main and in v0.9.0.

The fix (e14eb30) is on main and in v0.9.0.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: twisla/roro9stack#46