{"record":{"id":"5ab24ffa8733ca8a","repo":"gofiber/fiber","slug":"unexpected-error-when-trying-to-remove-unix-socket","errorCode":null,"errorMessage":"unexpected error when trying to remove unix socket file %q: %w","messagePattern":"unexpected error when trying to remove unix socket file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"listen.go","lineNumber":468,"sourceCode":"\tif cfg.EnablePrefork {\n\t\tlog.Warn(\"Prefork isn't supported for custom listeners.\")\n\t}\n\n\treturn app.server.Serve(ln)\n}\n\n// Create listener function.\nfunc (*App) createListener(addr string, tlsConfig *tls.Config, cfg *ListenConfig) (net.Listener, error) {\n\tif cfg == nil {\n\t\tcfg = &ListenConfig{}\n\t}\n\tvar listener net.Listener\n\tvar err error\n\n\t// Remove previously created socket, to make sure it's possible to listen\n\tif cfg.ListenerNetwork == NetworkUnix {\n\t\tif err = os.Remove(addr); err != nil && !os.IsNotExist(err) {\n\t\t\treturn nil, fmt.Errorf(\"unexpected error when trying to remove unix socket file %q: %w\", addr, err)\n\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","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/listen.go#L450-L486","documentation":"Returned by createListener when, for a Unix socket listener (ListenerNetwork == \"unix\"), os.Remove on the socket path fails with an error other than 'not exist'. Fiber pre-removes a stale socket so a restart can re-bind; any removal failure that is not ENOENT (the benign case) is treated as fatal because the subsequent net.Listen would inherit a broken state.","triggerScenarios":"The socket path exists as a regular file or directory rather than a stale socket; the path's parent directory is on a read-only filesystem; the running user lacks delete permission on the existing socket (created by a previous run as a different user); EBUSY on some platforms; the path crosses a filesystem boundary with restrictive mount options.","commonSituations":"Previous Fiber instance ran as root and created the socket; the new instance runs as an unprivileged user that cannot unlink it; the socket path was accidentally replaced by a log file or directory (e.g. logrotate misconfiguration); container restart where the volume is mounted read-only.","solutions":["Inspect the path: ls -la <socket-path> and confirm it is a socket (type 's'), not a file/dir.","Run both the previous and current instance under the same user, or chown the parent dir so the runtime user can unlink.","Delete the stale entry manually: rm -f <socket-path>.","If the parent directory is read-only, move the socket to a writable directory and update the addr.","Ensure systemd's ListenStream= or RuntimeDirectory= is not also managing the same path."],"exampleFix":"// before: previous run as root left /run/fiber.sock owned by root\napp.Listen(\"/run/fiber.sock\", fiber.ListenConfig{ListenerNetwork: fiber.NetworkUnix})\n\n// after: run as the same user / chown the socket dir, or use a runtime dir you own\napp.Listen(\"/run/fiber/fiber.sock\", fiber.ListenConfig{ListenerNetwork: fiber.NetworkUnix, UnixSocketFileMode: 0o660})","handlingStrategy":"validation","validationCode":"func checkUnixSocketPath(path string) error {\n    abs, err := filepath.Abs(path)\n    if err != nil { return err }\n    parent := filepath.Dir(abs)\n    info, err := os.Stat(parent)\n    if err != nil { return fmt.Errorf(\"socket parent dir: %w\", err) }\n    if !info.IsDir() { return fmt.Errorf(\"socket parent %q is not a directory\", parent) }\n    // best-effort: try to create+remove a file to confirm write access\n    probe := filepath.Join(parent, \".fiber-probe\")\n    f, err := os.Create(probe)\n    if err != nil { return fmt.Errorf(\"socket dir not writable: %w\", err) }\n    _ = f.Close()\n    _ = os.Remove(probe)\n    // if the socket already exists, try to remove it now\n    if _, err := os.Stat(abs); err == nil {\n        if err := os.Remove(abs); err != nil {\n            return fmt.Errorf(\"cannot remove existing socket %q: %w\", abs, err)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run all instances of the service as the same user.","Use a dedicated writable runtime directory (e.g. /run/<service>/).","Stop the previous instance before starting a new one.","Avoid co-locating logs and sockets in the same path namespace."],"tags":["unix-socket","filesystem","permissions","startup","listen"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}