amir20/dozzle · warning

Bad Request

Error message

Bad Request

What it means

In forward-proxy auth, the container filter header is parsed with container.ParseContainerFilter; a malformed filter expression logs a warning and the middleware rejects the request with 400 Bad Request. It is not an authentication failure, but a malformed label-filter header from the proxy.

Solutions

  1. Fix the container filter expression sent by the proxy to valid key=value label syntax
  2. Check proxy configuration (e.g. Authelia authn rules) for the header that carries the filter
  3. Temporarily remove the filter header to confirm it is the failing part
  4. Check Dozzle logs for the 'Failed to parse container filter' warning showing the bad value

Example fix

// before (proxy sends malformed filter)
http.Header{"X-Container-Filter": {"name==foo"}}
// after
http.Header{"X-Container-Filter": {"name=foo"}}
Defensive patterns

Strategy: validation

Validate before calling

const filter = req.headers['x-container-filter'];
if (filter && !/^[\w.-]+=(~?[\w.*-]+|[\w.-]+=[\w.*-]+)(,[\w.-]+=(~?[\w.*-]+))*$/.test(filter)) {
  throw new Error(`invalid container filter: ${filter}`);
}

Try / catch

proxy.on('proxyRes', res => {
  const f = res.headers['x-container-filter'];
  if (f && !isValidFilter(f)) delete res.headers['x-container-filter'];
});

Prevention

When it happens

Trigger: Forward auth proxy (e.g. Authelia) sends a non-empty filter header that does not parse as a valid container label filter (bad syntax, unbalanced expressions, wrong key=value form).

Common situations: Misconfigured proxy response headers mapping the wrong upstream header into the filter slot; users crafting label expressions with typos; proxy URL-decoding mangling special characters.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at internal/auth/proxy.go:56

}

func NewForwardProxyAuth(userHeader, emailHeader, nameHeader, filterHeader, rolesHeader string) *proxyAuthContext {
	return &proxyAuthContext{
		headerUser:   userHeader,
		headerEmail:  emailHeader,
		headerName:   nameHeader,
		headerFilter: filterHeader,
		headerRoles:  rolesHeader,
	}
}

func (p *proxyAuthContext) AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get(p.headerUser) != "" {
			containerFilter, err := container.ParseContainerFilter(r.Header.Get(p.headerFilter))
			if err != nil {
				log.Warn().Err(err).Str("filter", r.Header.Get(p.headerFilter)).Msg("Failed to parse container filter")
				http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
				return
			}
			userRoles := All
			if strings.TrimSpace(r.Header.Get(p.headerRoles)) != "" {
				userRoles = ParseRole(r.Header.Get(p.headerRoles))
			}
			user := newUser(r.Header.Get(p.headerUser), r.Header.Get(p.headerEmail), r.Header.Get(p.headerName), containerFilter, userRoles)
			ctx := WithUser(r.Context(), user)
			next.ServeHTTP(w, r.WithContext(ctx))
		} else {
			next.ServeHTTP(w, r)
		}
	})
}

func (p *proxyAuthContext) CreateToken(username, password string) (string, error) {
	log.Fatal().Msg("CreateToken not implemented in proxy auth")
	return "", nil

View on GitHub (pinned to d9463cbe21)