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

  1. Verify the password exactly matches the Pi-hole v6 web UI password (quote it in YAML if it has special characters).
  2. curl -X POST {url}/api/auth -d '{"password":"..."}' and confirm a 200 with a session.sid.
  3. Check network reachability/TLS from the glance host; set allow-insecure: true only for self-signed labs.
  4. 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

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


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/b21247518e8379b8. Report an issue: GitHub.