{"record":{"id":"541bbf59fe8d526d","repo":"amir20/dozzle","slug":"unable-to-find-user","errorCode":null,"errorMessage":"Unable to find user","messagePattern":"Unable to find user","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/web/profile.go","lineNumber":30,"sourceCode":"func (h *handler) updateProfile(w http.ResponseWriter, r *http.Request) {\n\tusername := profile.DefaultUsername\n\tif user := auth.UserFromContext(r.Context()); user != nil {\n\t\tusername = user.Username\n\t}\n\n\tif err := profile.UpdateFromReader(username, r.Body); err != nil {\n\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()","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/web/profile.go#L12-L48","documentation":"The avatar handler looks up the authenticated user via auth.UserFromContext. When no user is present in the request context (which happens when authentication is misconfigured, the JWT is missing/invalid, or the auth middleware did not run), it returns 'Unable to find user' with HTTP 500.","triggerScenarios":"GET /api/profile/avatar without a valid session: auth provider is enabled but the request lacks the JWT cookie, the token is expired or signed with a different shared key, or the route was accessed without going through the auth middleware.","commonSituations":"JWT TTL expired while the SPA still calls the avatar endpoint; server restarted with a regenerated shared_cert/shared_key invalidating old tokens; calling the endpoint directly with curl without the Authorization/cookie header; provider mismatch between frontend expectations and backend config.","solutions":["Re-authenticate: log in again so a fresh JWT cookie is issued.","Check that the request actually includes the auth cookie/token when calling the endpoint.","If tokens stopped working after a restart, ensure the certificate/shared key files were not regenerated unexpectedly.","Verify the avatar route is registered behind the auth middleware in routes.go.","If auth is not intended, confirm the authorization provider is set to none."],"exampleFix":"// before: calling avatar without credentials\ncurl http://dozzle:8080/api/profile/avatar\n// after: send the session cookie\ncurl -b \"jwt=<token>\" http://dozzle:8080/api/profile/avatar","handlingStrategy":"try-catch","validationCode":"// only call avatar endpoints when a session exists\nif (!config.user) return null;","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch('/api/profile/avatar');\n  if (res.status === 500) return DEFAULT_AVATAR; // no user in session\n  return URL.createObjectURL(await res.blob());\n} catch { return DEFAULT_AVATAR; }","preventionTips":["Refresh auth tokens before they expire","Do not regenerate shared certificates on routine restarts","Keep avatar/profile routes behind the auth middleware consistently"],"tags":["auth","http","session"],"backgroundTag":"user-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"}