glanceapp/glance · error
fetching session ID: %v
Error message
fetching session ID: %v
What it means
Returned by the Pi-hole v6 stats fetcher when no cached session ID exists and fetchPiholeSessionID fails to obtain one via POST /api/auth. The wrapped error is one of: creating/sending the auth request, reading/parsing its response, a non-200 status, or an empty SID. The failure is also logged via slog before being returned.
Source
Thrown at internal/glance/widget-dns-stats.go:435
includeGraph bool,
includeTopDomains bool,
) (*dnsStats, string, error) {
instanceURL = strings.TrimRight(instanceURL, "/")
var client = ternary(allowInsecure, defaultInsecureHTTPClient, defaultHTTPClient)
fetchNewSessionID := func() error {
newSessionID, err := fetchPiholeSessionID(instanceURL, client, password)
if err != nil {
return err
}
sessionID = newSessionID
return nil
}
if sessionID == "" {
if err := fetchNewSessionID(); err != nil {
slog.Error("Failed to fetch Pihole v6 session ID", "error", err)
return nil, "", fmt.Errorf("fetching session ID: %v", err)
}
} else {
isValid, err := checkPiholeSessionIDIsValid(instanceURL, client, sessionID)
if err != nil {
slog.Error("Failed to check Pihole v6 session ID validity", "error", err)
return nil, "", fmt.Errorf("checking session ID: %v", err)
}
if !isValid {
if err := fetchNewSessionID(); err != nil {
slog.Error("Failed to renew Pihole v6 session ID", "error", err)
return nil, "", fmt.Errorf("renewing session ID: %v", err)
}
}
}
var wg sync.WaitGroup
ctx, cancel := context.WithCancel(context.Background())View on GitHub (pinned to 91324e8de7)
Solutions
- Verify the password exactly matches the Pi-hole v6 web UI password (quote it in YAML if it has special characters).
- curl -X POST {url}/api/auth -d '{"password":"..."}' and confirm a 200 with a session.sid.
- Check network reachability/TLS from the glance host; set allow-insecure: true only for self-signed labs.
- Confirm the instance really runs Pi-hole v6 — v5 instances need service: pihole instead.
Example fix
# before - type: dns-stats service: pihole_v6 url: http://pihole.local/admin password: my$ecret # after - type: dns-stats service: pihole_v6 url: http://pihole.local password: "my$ecret"
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: can we authenticate at all?
if sid, err := fetchPiholeSessionID(url, client, password); err != nil {
return fmt.Errorf("pihole_v6 auth preflight failed: %v", err)
} else if sid == "" {
return errors.New("pihole_v6 returned empty session")
} Try / catch
stats, sid, err := fetchPiholeV6Stats(...)
if err != nil && strings.HasPrefix(err.Error(), "fetching session ID") {
// auth path failure: check password/reachability, skip this refresh
slog.Warn("pihole auth failed", "error", err)
return
} Prevention
- Quote the password in YAML to protect special characters.
- Confirm Pi-hole v6 (not v5) — v5 needs service: pihole.
- Point url at the instance root; the code appends /api paths.
When it happens
Trigger: widget.Service=pihole_v6 with a wrong password (auth returns 401), unreachable instance URL, TLS errors when allow-insecure is not set, or an auth response that is not the expected JSON.
Common situations: Pi-hole upgraded to v6 where the old ?auth= query param no longer works; password containing characters needing YAML quoting; glance running in a different network that cannot reach the Pi-hole host.
Related errors
- checking session ID: %v
- renewing session ID: %v
- fetching stats: %v
- could not fetch list of watch UUIDs: %v
- sending authentication request: %v
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/b21247518e8379b8.
Report an issue: GitHub.