amir20/dozzle · error
invalid auth realm
Error message
invalid auth realm %q: %w
What it means
In Registry.token the WWW-Authenticate challenge's realm string could not be parsed as a URL (url.Parse failed), so the registry returned a malformed token endpoint. The registry URL comes from the registry's own response header, meaning the upstream registry is misbehaving; the error wraps the underlying parse error via %w.
Solutions
- Inspect the registry's WWW-Authenticate header; the realm must be an absolute URL.
- Retry the check later if the registry is misconfigured server-side.
- Treat image update checks as best-effort: log and skip the update check instead of failing the request.
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at internal/imagecheck/registry.go:158 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/938002c3d1c0c686.
Report an issue: GitHub.
Appendix: source
Thrown at internal/imagecheck/registry.go:158
func (r *Registry) token(ctx context.Context, ref Reference, challenge string) (string, error) {
key := ref.host() + "/" + ref.Repository
r.mu.Lock()
if cached, ok := r.tokens[key]; ok && time.Now().Before(cached.expiresAt) {
r.mu.Unlock()
log.Debug().Str("repository", ref.Repository).Msg("image update check: reusing cached token")
return cached.token, nil
}
r.mu.Unlock()
realm, service := parseChallenge(challenge)
if realm == "" {
return "", ErrAuthRequired
}
endpoint, err := url.Parse(realm)
if err != nil {
return "", fmt.Errorf("invalid auth realm %q: %w", realm, err)
}
// The realm is chosen by the registry, so it decides where Dozzle sends
// its next request. Requiring TLS stops a hostile or compromised registry
// from pointing that request at a plaintext internal address such as a
// cloud metadata endpoint. Loopback registries are exempt for the same
// reason they are allowed over HTTP at all.
if err := validateRealm(endpoint, ref); err != nil {
return "", err
}
query := endpoint.Query()
if service != "" {
query.Set("service", service)
}
query.Set("scope", "repository:"+ref.Repository+":pull")
endpoint.RawQuery = query.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)View on GitHub (pinned to d9463cbe21)