amir20/dozzle · warning
Forbidden
Error message
Forbidden
What it means
findContainerWithActions enforces that the authenticated user has the Actions role (or is admin) before performing start/stop/restart/update on a container. Without the role the handler logs a warning and returns 403 Forbidden.
Solutions
- Grant the user the actions role (admin level or explicit role in users.yml / proxy role header)
- Perform the action as an admin user
- If restriction is intentional, perform start/stop/restart with docker CLI instead
- Verify the proxy is forwarding the roles header if using forward auth
Example fix
# before (users.yml)
admin: {email: admin@example.com, password: "..."}
# after
admin: {email: admin@example.com, password: "...", name: admin, roles: [admin]} Defensive patterns
Strategy: validation
Validate before calling
const me = await (await fetch('/api/user', {credentials:'include'})).json();
const canAct = me.roles?.includes('admin') || me.roles?.includes('actions');
if (!canAct) console.warn('user lacks container action permissions'); Try / catch
const res = await fetch(actionUrl, {method: 'POST', credentials: 'include'});
if (res.status === 403) {
showError('Your account is not allowed to control containers');
} Prevention
- Grant the actions/admin role to users who need start/stop/restart
- Verify the proxy forwards the roles header in forward-auth setups
- Check permissions before rendering action buttons in custom UIs
When it happens
Trigger: POST /api/hosts/{host}/containers/{id}/actions/{action} or /update by a user whose roles lack auth.Actions; non-admin users in simple auth; forward-proxy setups mapping the user to a read-only role.
Common situations: Users file configured without the actions role in users.yml; proxy header omitting roles so defaults exclude Actions; orgs restricting destructive actions deliberately.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/02b52859f5101743.
Report an issue: GitHub.
Appendix: source
Thrown at internal/web/actions.go:29
"github.com/rs/zerolog/log"
)
func (h *handler) findContainerWithActions(w http.ResponseWriter, r *http.Request) (*container_support.ContainerService, bool) {
id := chi.URLParam(r, "id")
userLabels := h.config.Labels
permit := true
if h.config.Authorization.Provider != NONE {
user := auth.UserFromContext(r.Context())
if user.ContainerLabels.Exists() {
userLabels = user.ContainerLabels
}
permit = user.Roles.Has(auth.Actions)
}
if !permit {
log.Warn().Msg("user is not permitted to perform actions on container")
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return nil, false
}
containerService, err := h.hostService.FindContainer(hostKey(r), id, userLabels)
if err != nil {
log.Error().Err(err).Msg("error while trying to find container")
http.Error(w, err.Error(), http.StatusNotFound)
return nil, false
}
return containerService, true
}
func (h *handler) containerActions(w http.ResponseWriter, r *http.Request) {
action := chi.URLParam(r, "action")
containerService, ok := h.findContainerWithActions(w, r)
if !ok {View on GitHub (pinned to d9463cbe21)