glanceapp/glance · error

creating session ID check request: %v

Error message

creating session ID check request: %v

What it means

Thrown while building the GET <instanceURL>/api/auth request used to validate a Pi-hole session ID (header x-ftl-sid). http.NewRequest only fails when the URL cannot be parsed, so this indicates the configured Pi-hole instance URL is malformed (bad control characters, spaces, or an invalid scheme). The error wraps the underlying net/url parse error.

Source

Thrown at internal/glance/widget-dns-stats.go:669

			"authentication request returned status %s with message '%s'",
			response.Status, jsonResponse.Session.Message,
		)
	}

	if jsonResponse.Session.SID == "" {
		return "", fmt.Errorf(
			"authentication response returned empty session ID, status code %d, message '%s'",
			response.StatusCode, jsonResponse.Session.Message,
		)
	}

	return jsonResponse.Session.SID, nil
}

func checkPiholeSessionIDIsValid(instanceURL string, client *http.Client, sessionID string) (bool, error) {
	request, err := http.NewRequest("GET", instanceURL+"/api/auth", nil)
	if err != nil {
		return false, fmt.Errorf("creating session ID check request: %v", err)
	}
	request.Header.Set("x-ftl-sid", sessionID)

	response, err := client.Do(request)
	if err != nil {
		return false, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusUnauthorized {
		return false, fmt.Errorf("session ID check request returned status %s", response.Status)
	}

	return response.StatusCode == http.StatusOK, nil
}

type technitiumStatsResponse struct {
	Response struct {

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Check the widget's url: field for typos, spaces, or a missing http:// scheme
  2. Print/inspect the effective instanceURL value right before the call and test it with curl
  3. URL-encode any special characters in the URL (e.g. passwords in basic-auth path segments)

Example fix

# before
- type: pi-hole
  url: "http://192.168.1.10 :8080"
# after
- type: pi-hole
  url: "http://192.168.1.10:8080"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(instanceURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid pi-hole instance URL: %q", instanceURL)
}
sid, err := fetchPiholeSession(instanceURL, client) // then validate

Type guard

func isValidInstanceURL(raw string) bool {
    u, err := url.Parse(raw)
    return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}

Try / catch

if valid, err := checkPiholeSessionIDIsValid(url, client, sid); err != nil {
    slog.Warn("pi-hole session check failed", "url", url, "error", err)
    // fall back to unauthenticated stats rather than failing the widget
} else if valid {
    // use authenticated endpoint
}

Prevention

When it happens

Trigger: checkPiholeSessionIDIsValid(instanceURL, ...) is called with an instanceURL that url.Parse rejects, e.g. 'http://192.168.1.10 :8080' (space), a URL with a pipe/control character, or an unparseable value from the widget's url: YAML field.

Common situations: Typo in the widget's url: setting (trailing spaces, missing scheme, copied URL with special characters); environment variable interpolation producing an empty or garbage URL.

Related errors


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