{"id":"a3c2a416de6d61dc","repo":"gofiber/fiber","slug":"cannot-chmod-o-for-q-w","errorCode":null,"errorMessage":"cannot chmod %#o for %q: %w","messagePattern":"cannot chmod %#o for %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"listen.go","lineNumber":392,"sourceCode":"\t\t}\n\t}\n\n\tif tlsConfig != nil {\n\t\tlistener, err = tls.Listen(cfg.ListenerNetwork, addr, tlsConfig)\n\t} else {\n\t\tlistener, err = net.Listen(cfg.ListenerNetwork, addr)\n\t}\n\n\t// Check for error before using the listener\n\tif err != nil {\n\t\t// Wrap the error from tls.Listen/net.Listen\n\t\treturn nil, fmt.Errorf(\"failed to listen: %w\", err)\n\t}\n\n\tif cfg.ListenerNetwork == NetworkUnix {\n\t\tif err = os.Chmod(addr, cfg.UnixSocketFileMode); err != nil {\n\t\t\t_ = listener.Close() //nolint:errcheck // best-effort cleanup on the error path\n\t\t\treturn nil, fmt.Errorf(\"cannot chmod %#o for %q: %w\", cfg.UnixSocketFileMode, addr, err)\n\t\t}\n\t}\n\n\tif cfg.ListenerAddrFunc != nil {\n\t\tcfg.ListenerAddrFunc(listener.Addr())\n\t}\n\n\treturn listener, nil\n}\n\nfunc (app *App) printMessages(cfg *ListenConfig, listenData *ListenData) {\n\tapp.startupMessage(listenData, cfg)\n\n\tif cfg.EnablePrintRoutes {\n\t\tapp.printRoutesMessage()\n\t}\n}\n","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/listen.go#L374-L410","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before: binding in a root-owned dir, chmod 0660 fails for non-root\napp.Listen(\"/var/run/app.sock\", fiber.ListenConfig{\n  ListenerNetwork:    fiber.NetworkUnix,\n  UnixSocketFileMode: 0o660,\n})\n\n// after: use a writable per-app dir\nos.MkdirAll(\"/var/lib/app\", 0o755)\napp.Listen(\"/var/lib/app/app.sock\", fiber.ListenConfig{\n  ListenerNetwork:    fiber.NetworkUnix,\n  UnixSocketFileMode: 0o660,\n})","handlingStrategy":"validation","validationCode":"// Ensure the socket's parent dir is writable by this process before listening.\nfunc ensureWritableSocketDir(path string) error {\n    dir := filepath.Dir(path)\n    if err := os.MkdirAll(dir, 0o755); err != nil {\n        return fmt.Errorf(\"mkdir %q: %w\", dir, err)\n    }\n    probe := filepath.Join(dir, \".writeprobe\")\n    f, err := os.Create(probe)\n    if err != nil {\n        return fmt.Errorf(\"dir %q not writable: %w\", dir, err)\n    }\n    _ = f.Close()\n    _ = os.Remove(probe)\n    return nil\n}","typeGuard":"null","tryCatchPattern":"err := app.Listen(sock, fiber.ListenConfig{\n    ListenerNetwork:    fiber.NetworkUnix,\n    UnixSocketFileMode: 0o660,\n})\nif err != nil && strings.Contains(err.Error(), \"cannot chmod\") {\n    log.Errorf(\"post-listen chmod failed — check parent dir perms: %v\", err)\n}","preventionTips":["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."],"tags":["unix-socket","filesystem","permissions","startup","hardening"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}