{"record":{"id":"07ab5423e25c16d7","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-dial-socket-path-q-w","errorCode":null,"errorMessage":"cannot dial socket path %q: %w","messagePattern":"cannot dial socket path %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/netutil/unixlistener.go","lineNumber":71,"sourceCode":"\t\treturn fmt.Errorf(\"file %q already exists and is not a socket\", addr)\n\t}\n\n\tconn, err := net.DialTimeout(\"unix\", addr, 100*time.Millisecond)\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\t// File does not exist.\n\t\t\treturn nil\n\t\t}\n\t\tif errors.Is(err, syscall.ECONNREFUSED) {\n\t\t\t// File exists, but there is no listener.\n\t\t\t// This may happen in case of unclean shutdown, so remove it.\n\t\t\tif err := os.Remove(addr); err != nil {\n\t\t\t\treturn fmt.Errorf(\"cannot remove exist socket path: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\t// Could be access denied or other unrelated errors.\n\t\treturn fmt.Errorf(\"cannot dial socket path %q: %w\", addr, err)\n\t}\n\t_ = conn.Close()\n\treturn fmt.Errorf(\"another process is already listening on %q\", addr)\n}\n\n// UnixListener listens for the addr passed to NewUnixListener.\n//\n// It also gathers various stats for the accepted connections.\ntype UnixListener struct {\n\t*net.UnixListener\n\n\taccepts      *metrics.Counter\n\tacceptErrors *metrics.Counter\n\n\tcm connMetrics\n}\n\n// Accept accepts connections from the addr passed to NewUnixListener.","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/netutil/unixlistener.go#L53-L89","documentation":"removePreviousSocketFile dials the existing socket path to test liveness; any dial error other than ENOENT or ECONNREFUSED (e.g. EACCES — access denied) is not safely interpretable, so it is wrapped and returned instead of unlinking the file. This prevents deleting a socket that might belong to a running process the caller cannot even probe.","triggerScenarios":"NewUnixListener is called with an addr where a socket file exists but net.DialTimeout fails with a non-ENOENT/non-ECONNREFUSED error — most commonly EACCES because the current user cannot read/write the socket file or traverse its directory.","commonSituations":"Socket created by another user or in a directory with restrictive permissions, AppArmor/SELinux denials, or a socket under a path with no execute permission for the current user.","solutions":["Inspect the wrapped %w error (often 'connect: permission denied')","Fix permissions so the current user can access the socket path and its parent directories (chmod/chown)","Remove the socket file manually if you are certain no process is using it","Run the process under the same user that created the previous socket"],"exampleFix":"// before\n$ ls -l /run/vm.sock  # srw------- root root\n$ ./victoria-metrics -unixListenAddr /run/vm.sock  # EACCES\n// after\n$ sudo rm /run/vm.sock   # or chown/chmod so the service user can access it","handlingStrategy":"try-catch","validationCode":"import \"net\"\nimport \"os\"\nimport \"time\"\n\nfunc socketIsAccessible(addr string) error {\n\tif _, err := os.Lstat(addr); err != nil {\n\t\treturn nil // no file, nothing to probe\n\t}\n\tconn, err := net.DialTimeout(\"unix\", addr, 100*time.Millisecond)\n\tif err != nil {\n\t\treturn nil // will be handled by the library (refused/not-exist)\n\t}\n\tconn.Close()\n\treturn fmt.Errorf(\"already listening on %s\", addr)\n}","typeGuard":null,"tryCatchPattern":"ln, err := netutil.NewUnixListener(sockPath)\nif err != nil {\n\tif strings.Contains(err.Error(), \"cannot dial socket path\") {\n\t\tvar se syscall.Errno\n\t\tif errors.As(err, &se) && se == syscall.EACCES {\n\t\t\tlog.Fatalf(\"no permission to probe %s; fix socket/dir ownership\", sockPath)\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Run the service as the same user that previously created the socket","Grant traverse (x) permission on all parent directories of the socket path","Check SELinux/AppArmor audit logs if permissions look correct","Prefer a per-service socket directory owned by the service user"],"tags":["unix-socket","permissions","dial","go"],"backgroundTag":"unix-socket-access-denied","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}