gofiber/fiber · error
cannot chmod %#o for %q: %w
Error message
cannot chmod %#o for %q: %w
What it means
Raised by createListener after a unix-domain listener is successfully created but os.Chmod of the socket path to cfg.UnixSocketFileMode fails. The chmod is intentional hardening so only the intended users can connect to the socket; on failure Fiber closes the listener and returns the error rather than leaving the socket with default (often world-readable) permissions. The %#o prints the requested octal mode in the message.
Source
Thrown at listen.go:392
}
}
if tlsConfig != nil {
listener, err = tls.Listen(cfg.ListenerNetwork, addr, tlsConfig)
} else {
listener, err = net.Listen(cfg.ListenerNetwork, addr)
}
// Check for error before using the listener
if err != nil {
// Wrap the error from tls.Listen/net.Listen
return nil, fmt.Errorf("failed to listen: %w", err)
}
if cfg.ListenerNetwork == NetworkUnix {
if err = os.Chmod(addr, cfg.UnixSocketFileMode); err != nil {
_ = listener.Close() //nolint:errcheck // best-effort cleanup on the error path
return nil, fmt.Errorf("cannot chmod %#o for %q: %w", cfg.UnixSocketFileMode, addr, err)
}
}
if cfg.ListenerAddrFunc != nil {
cfg.ListenerAddrFunc(listener.Addr())
}
return listener, nil
}
func (app *App) printMessages(cfg *ListenConfig, listenData *ListenData) {
app.startupMessage(listenData, cfg)
if cfg.EnablePrintRoutes {
app.printRoutesMessage()
}
}
View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Ensure the process owns (or can write) both the socket file and its parent directory.
- Place the socket in a directory the process fully controls, e.g. /run/user/<uid>/ or a dedicated /var/lib/<app> dir.
- Disable or adjust any cron/systemd unit that aggressively cleans the socket directory.
- If SELinux/AppArmor is involved, allow chmod on the socket path's type in the policy.
- Verify cfg.UnixSocketFileMode is a sane octal like 0o660 (avoid unset/zero).
Example fix
// before: binding in a root-owned dir, chmod 0660 fails for non-root
app.Listen("/var/run/app.sock", fiber.ListenConfig{
ListenerNetwork: fiber.NetworkUnix,
UnixSocketFileMode: 0o660,
})
// after: use a writable per-app dir
os.MkdirAll("/var/lib/app", 0o755)
app.Listen("/var/lib/app/app.sock", fiber.ListenConfig{
ListenerNetwork: fiber.NetworkUnix,
UnixSocketFileMode: 0o660,
}) Defensive patterns
Strategy: validation
Validate before calling
// Ensure the socket's parent dir is writable by this process before listening.
func ensureWritableSocketDir(path string) error {
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("mkdir %q: %w", dir, err)
}
probe := filepath.Join(dir, ".writeprobe")
f, err := os.Create(probe)
if err != nil {
return fmt.Errorf("dir %q not writable: %w", dir, err)
}
_ = f.Close()
_ = os.Remove(probe)
return nil
} Type guard
null
Try / catch
err := app.Listen(sock, fiber.ListenConfig{
ListenerNetwork: fiber.NetworkUnix,
UnixSocketFileMode: 0o660,
})
if err != nil && strings.Contains(err.Error(), "cannot chmod") {
log.Errorf("post-listen chmod failed — check parent dir perms: %v", err)
} Prevention
- Place sockets in directories the process owns and can chmod.
- Avoid root-owned runtime dirs for non-root processes; use /run/user/<uid>.
- Disable socket-cleaning watchdogs that race with the listener.
- Use a sane explicit mode (0o660) rather than leaving UnixSocketFileMode zero.
When it happens
Trigger: ListenerNetwork is unix, the socket was bound (e.g. under /var/run), but chmod fails because: the parent dir lacks write permission for the current user, the socket was already removed by a concurrent cleanup, SELinux/AppArmor denies chmod on the type, or cfg.UnixSocketFileMode is a nonsensical value the syscall rejects.
Common situations: Running the process under a uid that can create but not chmod a file in /var/run (root-owned dir); a watchdog concurrently deletes idle sockets; container with a read-only /run; passing a mode constant that isn't valid octal.
Related errors
- unexpected error when trying to remove unix socket file %q:
- open file error: %w
- failed to check directory: %w
- failed to create directory: %w
- failed to create file: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/a3c2a416de6d61dc.json.
Report an issue: GitHub.