{"record":{"id":"0f28fde7ce695086","repo":"cloudreve/cloudreve","slug":"failed-to-delete-socket-file-q-w","errorCode":null,"errorMessage":"failed to delete socket file %q: %w","messagePattern":"failed to delete socket file %q: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"application/application.go","lineNumber":162,"sourceCode":"\t}\n\n\t// 如果启用了SSL\n\tif s.config.SSL().CertPath != \"\" {\n\t\ts.logger.Info(\"Listening to %q\", s.config.SSL().Listen)\n\t\ts.server.Addr = s.config.SSL().Listen\n\t\tif err := s.server.ListenAndServeTLS(s.config.SSL().CertPath, s.config.SSL().KeyPath); err != nil && !errors.Is(err, http.ErrServerClosed) {\n\t\t\treturn fmt.Errorf(\"failed to listen to %q: %w\", s.config.SSL().Listen, err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\t// 如果启用了Unix\n\tif s.config.Unix().Listen != \"\" {\n\t\t// delete socket file before listening\n\t\tif _, err := os.Stat(s.config.Unix().Listen); err == nil {\n\t\t\tif err = os.Remove(s.config.Unix().Listen); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to delete socket file %q: %w\", s.config.Unix().Listen, err)\n\t\t\t}\n\t\t}\n\n\t\ts.logger.Info(\"Listening to %q\", s.config.Unix().Listen)\n\t\tif err := s.runUnix(s.server); err != nil && !errors.Is(err, http.ErrServerClosed) {\n\t\t\treturn fmt.Errorf(\"failed to listen to %q: %w\", s.config.Unix().Listen, err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\ts.logger.Info(\"Listening to %q\", s.config.System().Listen)\n\ts.server.Addr = s.config.System().Listen\n\tif err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {\n\t\treturn fmt.Errorf(\"failed to listen to %q: %w\", s.config.System().Listen, err)\n\t}\n\treturn nil\n}","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/cloudreve/cloudreve/blob/20c95ad73f3a8bcb72887fea91ff31ab24fa1011/application/application.go#L144-L180","documentation":"Returned during Unix-socket boot when a stale socket file exists at the configured path but os.Remove fails. The server proactively deletes the leftover socket before listening (a bound socket file from a crashed previous run would make Listen fail with 'address already in use'), and this error means the cleanup itself could not complete.","triggerScenarios":"config Unix().Listen is set, the file at that path exists (previous unclean shutdown), and the process lacks write/parent-directory permission to remove it, or the path is actually a directory.","commonSituations":"Running the service under a different, unprivileged user than the one that created the socket; socket path on a read-only mount; path accidentally created as a directory (bad config or manual mistake); SELinux/AppArmor denying unlink.","solutions":["Check the wrapped error for EACCES/EISDIR/EROFS to identify the cause","Manually remove the stale file: rm /path/to/cloudreve.sock, or fix ownership so the service user can unlink it","If the path is a directory, correct the Unix.Listen value in conf","Ensure the service user owns the socket's parent directory"],"exampleFix":"# before: stale socket owned by root, service runs as cloudreve\n# boot fails: failed to delete socket file\n\n# after\nsudo rm /run/cloudreve.sock && sudo chown cloudreve /run && systemctl start cloudreve","handlingStrategy":"validation","validationCode":"// Clean/verify the socket path before boot\nif p := cfg.Unix().Listen; p != \"\" {\n    if fi, err := os.Stat(p); err == nil {\n        if fi.IsDir() {\n            return fmt.Errorf(\"socket path %q is a directory\", p)\n        }\n        if err := os.Remove(p); err != nil {\n            return fmt.Errorf(\"cannot remove stale socket (check ownership): %w\", err)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give the service user ownership of the socket's parent directory","Use systemd's RuntimeDirectory= so stale sockets are cleaned each start","Never point Unix.Listen at a directory; validate config in deploy checks"],"tags":["startup","unix-socket","filesystem","permissions","configuration"],"backgroundTag":null,"analyzedSha":"20c95ad73f3a8bcb72887fea91ff31ab24fa1011","analyzedAt":"2026-08-16T01:42:55.403Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}