gofiber/fiber · error
unexpected error when trying to remove unix socket file
Error message
unexpected error when trying to remove unix socket file %q: %w
What it means
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.
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.
Example fix
// before: previous run as root left /run/fiber.sock owned by root
app.Listen("/run/fiber.sock", fiber.ListenConfig{ListenerNetwork: fiber.NetworkUnix})
// after: run as the same user / chown the socket dir, or use a runtime dir you own
app.Listen("/run/fiber/fiber.sock", fiber.ListenConfig{ListenerNetwork: fiber.NetworkUnix, UnixSocketFileMode: 0o660}) Defensive patterns
Strategy: validation
Validate before calling
func checkUnixSocketPath(path string) error {
abs, err := filepath.Abs(path)
if err != nil { return err }
parent := filepath.Dir(abs)
info, err := os.Stat(parent)
if err != nil { return fmt.Errorf("socket parent dir: %w", err) }
if !info.IsDir() { return fmt.Errorf("socket parent %q is not a directory", parent) }
// best-effort: try to create+remove a file to confirm write access
probe := filepath.Join(parent, ".fiber-probe")
f, err := os.Create(probe)
if err != nil { return fmt.Errorf("socket dir not writable: %w", err) }
_ = f.Close()
_ = os.Remove(probe)
// if the socket already exists, try to remove it now
if _, err := os.Stat(abs); err == nil {
if err := os.Remove(abs); err != nil {
return fmt.Errorf("cannot remove existing socket %q: %w", abs, err)
}
}
return nil
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- cannot chmod %#o for
- failed to read client CA file
- failed to check directory
- failed to create directory
- failed to parse client CA certificate from
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/5ab24ffa8733ca8a.
Report an issue: GitHub.
Appendix: source
Thrown at listen.go:468
if cfg.EnablePrefork {
log.Warn("Prefork isn't supported for custom listeners.")
}
return app.server.Serve(ln)
}
// Create listener function.
func (*App) createListener(addr string, tlsConfig *tls.Config, cfg *ListenConfig) (net.Listener, error) {
if cfg == nil {
cfg = &ListenConfig{}
}
var listener net.Listener
var err error
// Remove previously created socket, to make sure it's possible to listen
if cfg.ListenerNetwork == NetworkUnix {
if err = os.Remove(addr); err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("unexpected error when trying to remove unix socket file %q: %w", addr, err)
}
}
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 pathView on GitHub (pinned to a105acad6c)