caddyserver/caddy · error
unable to set permissions (%s) on %s: %v
Error message
unable to set permissions (%s) on %s: %v
What it means
After creating a unix (non-abstract) listener, Caddy applies the configured permission bits with os.Chmod on the socket path. This error wraps a chmod failure: the path disappeared, the process lacks ownership/chmod rights, or the filesystem rejected the operation.
Source
Thrown at listeners.go:199
lnKey := listenerKey(na.Network, address)
ln, err = listenReusable(ctx, lnKey, na.Network, address, config)
}
}
if err != nil {
return nil, err
}
if ln == nil {
return nil, fmt.Errorf("unsupported network type: %s", na.Network)
}
if IsUnixNetwork(na.Network) {
isAbstractUnixSocket := strings.HasPrefix(address, "@")
if !isAbstractUnixSocket {
err = os.Chmod(address, unixFileMode)
if err != nil {
return nil, fmt.Errorf("unable to set permissions (%s) on %s: %v", unixFileMode, address, err)
}
}
}
return ln, nil
}
// IsUnixNetwork returns true if na.Network is
// unix, unixgram, or unixpacket.
func (na NetworkAddress) IsUnixNetwork() bool {
return IsUnixNetwork(na.Network)
}
// IsFdNetwork returns true if na.Network is
// fd or fdgram.
func (na NetworkAddress) IsFdNetwork() bool {
return IsFdNetwork(na.Network)
}View on GitHub (pinned to 50e54ee279)
Solutions
- Ensure the Caddy process user owns or can chmod the socket path (systemd RuntimeDirectory=/run/caddy).
- Remove stale socket files before start or enable Caddy's unix socket reuse.
- Move the socket to a directory the service fully controls.
Example fix
# before: /run owned by root, caddy runs as caddy listen unix/run/caddy.sock # after (systemd unit) [Service] RuntimeDirectory=caddy listen unix/run/caddy/caddy.sock
Defensive patterns
Strategy: validation
Validate before calling
func canChmod(path string) bool {
info, err := os.Stat(path)
return err == nil && info.Mode().IsRegular() == false || err == nil
} Prevention
- Run Caddy with a dedicated RuntimeDirectory so it owns the socket path.
- Clean stale socket files before bind in service pre-start hooks.
When it happens
Trigger: Unix socket at a path the Caddy user cannot chmod (root-owned dir where the socket was created by another user), the socket file removed between bind and chmod by a cleanup race, or a filesystem that does not permit chmod (some network/ephemeral mounts).
Common situations: Running Caddy as non-root writing into /run without RuntimeDirectory; a second process deleting the socket concurrently; unusual container volumes mounted with restricted options.
Related errors
- checking if default Caddyfile exists: %v
- reading default Caddyfile: %v
- backing up current binary: %v
- unable to open destination file: %v
- could not parse octal permission bits in %s: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/9fe02a2fe6f61bf7.
Report an issue: GitHub.