amir20/dozzle · error

Unauthorized user

Error message

Unauthorized user

What it means

In forward-proxy auth mode, executeTemplate requires the authenticating proxy to inject Remote-Email, Remote-User, and Remote-Name headers. When none are present the request is rejected with 401 "Unauthorized user" because Dozzle cannot identify the user.

Solutions

  1. Access Dozzle only through the authenticating reverse proxy, not its exposed port.
  2. Configure the proxy to forward Remote-Email, Remote-User, and Remote-Name headers.
  3. Re-authenticate with the proxy provider if the session expired.

Example fix

# before (nginx, no headers)
proxy_pass http://dozzle:8080;
# after
proxy_set_header Remote-User $remote_user;
proxy_set_header Remote-Email $remote_user@example.com;
proxy_set_header Remote-Name $remote_user;
proxy_pass http://dozzle:8080;
Defensive patterns

Strategy: validation

Validate before calling

// client-side: detect the 401 and redirect through the proxy login
const res = await fetch('/', { redirect: 'manual' });
if (res.status === 401) location.href = '/login-path-of-your-proxy';

Prevention

When it happens

Trigger: Accessing any Dozzle page through a forward-proxy setup where the proxy does not set the Remote-* headers (unauthenticated request, misconfigured authelia/authentik bypass, direct access bypassing the proxy).

Common situations: Reaching Dozzle directly on its port instead of through the auth proxy; proxy configured but its forwarded header names customized without mapping; auth provider session expired and proxy let the request through unauthenticated.

Understand the failure class

Related errors


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

Appendix: source

Thrown at internal/web/index.go:80

func (h *handler) executeTemplate(w http.ResponseWriter, req *http.Request) {
	base := ""
	if h.config.Base != "/" {
		base = h.config.Base
	}

	user := auth.UserFromContext(req.Context())

	// Handle unauthorized cases early
	if user == nil {
		switch h.config.Authorization.Provider {
		case FORWARD_PROXY:
			log.Error().Msg("Unable to find remote user. Please check your proxy configuration. Expecting headers Remote-Email, Remote-User, Remote-Name.")
			log.Debug().Str("url", req.URL.String()).Msg("Dumping all headers for request")
			for k, v := range req.Header {
				log.Debug().Strs(k, v).Send()
			}
			http.Error(w, "Unauthorized user", http.StatusUnauthorized)
			return
		case SIMPLE:
			if req.URL.Path != "login" {
				log.Debug().Str("url", req.URL.String()).Msg("Redirecting to login page")
				http.Redirect(w, req, path.Clean(h.config.Base+"/login")+"?redirectUrl=/"+req.URL.String(), http.StatusTemporaryRedirect)
				return
			}
		}
	}

	config := map[string]any{
		"base": base,
	}

	// Build full config when authorized (no auth or authenticated user)
	if h.config.Authorization.Provider == NONE || user != nil {
		hosts := h.hostService.Hosts()
		sort.Slice(hosts, func(i, j int) bool {

View on GitHub (pinned to d9463cbe21)