glanceapp/glance · error

parsing authentication response: %v

Error message

parsing authentication response: %v

What it means

Returned by fetchPiholeSessionID when json.Unmarshal of the auth response body into {session:{sid,message}} fails. The endpoint replied but with a body that is not the expected JSON object — typically HTML (login/proxy error page) or an empty body, so unmarshal errors with 'invalid character' or 'unexpected end of JSON input'.

Source

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

	if err != nil {
		return "", fmt.Errorf("sending authentication request: %v", err)
	}
	defer response.Body.Close()

	body, err := io.ReadAll(response.Body)
	if err != nil {
		return "", fmt.Errorf("reading authentication response: %v", err)
	}

	var jsonResponse struct {
		Session struct {
			SID     string `json:"sid"`
			Message string `json:"message"`
		} `json:"session"`
	}

	if err := json.Unmarshal(body, &jsonResponse); err != nil {
		return "", fmt.Errorf("parsing authentication response: %v", err)
	}

	if response.StatusCode != http.StatusOK {
		return "", fmt.Errorf(
			"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
}

View on GitHub (pinned to 91324e8de7)

Solutions

  1. curl -i -X POST {url}/api/auth and inspect Content-Type and body — JSON is expected.
  2. Confirm the target actually runs Pi-hole v6 (v5 uses a different auth model; use service: pihole).
  3. Remove path suffixes from url so the API root is hit.
  4. Fix proxy rules that rewrite or redirect /api/auth.

Example fix

# before
url: http://pihole.local/admin
service: pihole_v6

# after
url: http://pihole.local
service: pihole_v6
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm the endpoint speaks v6 JSON before relying on it
req, _ := http.NewRequest("POST", instanceURL+"/api/auth", strings.NewReader(`{"password":"x"}`))
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err == nil {
    defer resp.Body.Close()
    if ct := resp.Header.Get("Content-Type"); !strings.Contains(ct, "json") {
        return errors.New("not a Pi-hole v6 API — body is not JSON")
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "parsing authentication response") {
    // HTML/empty body: wrong version, wrong path, or proxy interference
    slog.Error("pihole auth returned non-JSON; check url and version", "error", err)
}

Prevention

When it happens

Trigger: POST /api/auth returns an HTML page from a reverse proxy, a captive portal, or a redirect target; an empty 200 body; or a Pi-hole version whose /api/auth response shape differs (pre-v6 firmware without the v6 API).

Common situations: URL pointing at Pi-hole v5 (no /api/auth JSON contract); proxy redirecting http→https with an HTML interstitial; trailing path like /admin causing a UI page to be served.

Understand the failure class

Related errors


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