amir20/dozzle · info

Unable to find avatar

Error message

Unable to find avatar

What it means

After resolving the user, the avatar handler calls user.AvatarURL(). If the computed URL is empty (no avatar source configured for this auth mode), the handler returns 'Unable to find avatar' with HTTP 404 Not Found. This is an expected, controlled response indicating no avatar exists for the user.

Solutions

  1. Configure an avatar for the user: add an avatar or email field in users.yml (simple auth) so AvatarURL() can resolve an image.
  2. If using forward-proxy auth, forward the avatar/email header (e.g. Remote-Email or Remote-Avatar) from the proxy.
  3. Treat HTTP 404 from this endpoint as normal in clients and fall back to a default/placeholder avatar.
  4. Verify with --level trace that the handler is not reaching the 'Fetching avatar' log line, confirming the URL is indeed empty.

Example fix

// before: data/users.yml user without avatar
alice:
  name: Alice
  password: "$2a$..."
// after
alice:
  name: Alice
  email: alice@example.com
  password: "$2a$..."
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: GET /api/profile/avatar for a user whose auth provider does not supply an avatar image (e.g. simple file-based users.yml without an avatar field, or forward-proxy auth that did not pass an avatar header), so AvatarURL() returns the empty string.

Common situations: Simple auth users.yml entries lacking avatar/email used for gravatar-style lookup; Authelia or another proxy not forwarding the avatar or email header Dozzle maps to AvatarURL; new user account created without avatar attributes.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/7e421e16be403d67. Report an issue: GitHub.

Appendix: source

Thrown at internal/web/profile.go:37

		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Error().Err(err).Msg("Failed to update profile")
		return
	}

	w.WriteHeader(http.StatusOK)
}

func (h *handler) avatar(w http.ResponseWriter, r *http.Request) {
	user := auth.UserFromContext(r.Context())
	if user == nil {
		http.Error(w, "Unable to find user", http.StatusInternalServerError)
		return
	}

	url := user.AvatarURL()

	if url == "" {
		http.Error(w, "Unable to find avatar", http.StatusNotFound)
		return
	}

	log.Trace().Str("url", url).Msg("Fetching avatar")
	response, err := http.Get(url)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		log.Error().Str("url", url).Int("status", response.StatusCode).Msg("Failed to fetch avatar")
		return
	}

	w.Header().Set("Content-Type", response.Header.Get("Content-Type"))

View on GitHub (pinned to d9463cbe21)