{"record":{"id":"7e421e16be403d67","repo":"amir20/dozzle","slug":"unable-to-find-avatar","errorCode":null,"errorMessage":"Unable to find avatar","messagePattern":"Unable to find avatar","errorType":"http","errorClass":null,"httpStatus":404,"severity":"info","filePath":"internal/web/profile.go","lineNumber":37,"sourceCode":"\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\tlog.Error().Err(err).Msg(\"Failed to update profile\")\n\t\treturn\n\t}\n\n\tw.WriteHeader(http.StatusOK)\n}\n\nfunc (h *handler) avatar(w http.ResponseWriter, r *http.Request) {\n\tuser := auth.UserFromContext(r.Context())\n\tif user == nil {\n\t\thttp.Error(w, \"Unable to find user\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\turl := user.AvatarURL()\n\n\tif url == \"\" {\n\t\thttp.Error(w, \"Unable to find avatar\", http.StatusNotFound)\n\t\treturn\n\t}\n\n\tlog.Trace().Str(\"url\", url).Msg(\"Fetching avatar\")\n\tresponse, err := http.Get(url)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tdefer response.Body.Close()\n\n\tif response.StatusCode != http.StatusOK {\n\t\tlog.Error().Str(\"url\", url).Int(\"status\", response.StatusCode).Msg(\"Failed to fetch avatar\")\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", response.Header.Get(\"Content-Type\"))","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/web/profile.go#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Configure an avatar for the user: add an avatar or email field in users.yml (simple auth) so AvatarURL() can resolve an image.","If using forward-proxy auth, forward the avatar/email header (e.g. Remote-Email or Remote-Avatar) from the proxy.","Treat HTTP 404 from this endpoint as normal in clients and fall back to a default/placeholder avatar.","Verify with --level trace that the handler is not reaching the 'Fetching avatar' log line, confirming the URL is indeed empty."],"exampleFix":"// before: data/users.yml user without avatar\nalice:\n  name: Alice\n  password: \"$2a$...\"\n// after\nalice:\n  name: Alice\n  email: alice@example.com\n  password: \"$2a$...\"","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provide an avatar or email for users in users.yml","Forward avatar/email headers from forward-proxy auth","Always render a placeholder avatar when the endpoint returns 404"],"tags":["http","avatar","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}