MagicMirrorOrg/MagicMirror · warning
${this.logContext}${this.#shortenUrl()} - ${message} Retry #
Error message
${this.logContext}${this.#shortenUrl()} - ${message} Retry #${this.networkErrorCount} in ${Math.round(nextDelay / 1000)}s. What it means
In HTTPFetcher.fetch, when a network-level error occurs (fetch rejection such as DNS failure, connection refused/reset, timeout), the fetcher computes an exponential backoff via calculateBackoffDelay capped at reloadInterval, logs a retry message as warning for the first two attempts and error afterwards, and increments networkErrorCount for each subsequent retry.
Source
Thrown at js/http_fetcher.js:330
this.emit("error", errorInfo);
}
} catch (error) {
const isTimeout = error.name === "AbortError";
const message = isTimeout ? `Request timeout after ${this.timeout}ms` : `Network error: ${error.message}`;
this.networkErrorCount = Math.min(this.networkErrorCount + 1, this.maxRetries);
const exhausted = this.networkErrorCount >= this.maxRetries;
if (exhausted) {
nextDelay = this.reloadInterval;
Log.error(`${this.logContext}${this.#shortenUrl()} - ${message} Max retries reached, retrying at configured interval (${Math.round(nextDelay / 1000)}s).`);
} else {
nextDelay = HTTPFetcher.calculateBackoffDelay(this.networkErrorCount, {
maxDelay: this.reloadInterval
});
const retryMsg = `${this.logContext}${this.#shortenUrl()} - ${message} Retry #${this.networkErrorCount} in ${Math.round(nextDelay / 1000)}s.`;
if (this.networkErrorCount <= 2) {
Log.warn(retryMsg);
} else {
Log.error(retryMsg);
}
}
const errorInfo = this.#createErrorInfo(
message,
null,
"NETWORK_ERROR",
nextDelay,
error
);
this.emit("error", errorInfo);
} finally {
clearTimeout(timeoutId);
}
this.scheduleNextFetch(nextDelay);View on GitHub (pinned to 4b4a59534f)
Solutions
- Verify network connectivity from the mirror host (ping/curl the endpoint URL).
- Check the shortened URL in the log for a typo or expired domain; correct the address in the module config.
- Increase fetch_timeout or reloadInterval if the network is slow/flaky to give retries more room.
- Fix DNS/proxy/firewall settings so outbound HTTPS to the endpoint works.
- Wait — the fetcher retries automatically with exponential backoff capped at the reload interval.
Example fix
// before curl https://api.example.com/data # connection refused // after curl https://api.correct-domain.com/data # fix URL in module config / restore network
Defensive patterns
Strategy: retry
Validate before calling
// Before starting periodic fetches, verify reachability
async function reachable(url, timeoutMs = 5000) {
try {
const ctl = new AbortController();
const t = setTimeout(() => ctl.abort(), timeoutMs);
await fetch(url, { method: "HEAD", signal: ctl.signal });
clearTimeout(t);
return true;
} catch { return false;
}
} Type guard
function isNetworkError(err) {
return err instanceof TypeError || /ECONNREFUSED|ENOTFOUND|ETIMEDOUT|ECONNRESET/.test(err?.cause?.code ?? "");
} Try / catch
try {
const res = await fetchWithTimeout(url, 10000);
} catch (err) {
networkErrorCount++;
const nextDelay = Math.min(reloadInterval, 1000 * 2 ** networkErrorCount);
Log.warn(`${url} failed (${err.cause?.code ?? err.message}); retry #${networkErrorCount} in ${nextDelay / 1000}s`);
setTimeout(fetch, nextDelay);
} Prevention
- Monitor the Pi's WiFi/connection health (e.g. a watchdog or ping check).
- Pin and verify endpoint URLs; DNS typos show up as ENOTFOUND in the log.
- Set a sane fetch_timeout so hangs become recoverable errors instead of silent stalls.
- Cap backoff at reloadInterval (as the library does) so retries stay periodic.
When it happens
Trigger: fetch() throws while requesting a remote resource — unreachable host, offline network, TLS errors, connection timeout (connect timeout set by the undici Agent's fetch_timeout) — triggering the retry/backoff path.
Common situations: WiFi drop or router reboot on a Raspberry Pi; firewalled/air-gapped networks; the remote API endpoint being down or DNS misconfigured; invalid proxy settings blocking outbound HTTPS.
Related errors
- HTTP ${response.status}
- Failed to fetch grid point: HTTP ${pointsResponse.status}
- Failed to fetch observation stations: HTTP ${stationsRespons
- ${error.message}
- [compliments] Invalid URL: ${url}
AI-assisted analysis of MagicMirrorOrg/MagicMirror@4b4a59534f (2026-08-31).
Data as JSON: /api/errors/b07e2e1a3902b18d.
Report an issue: GitHub.