valyala/fasthttp · error

unexpected error when trying to remove unix socket file %q:

Error message

unexpected error when trying to remove unix socket file %q: %w

What it means

Returned by Server.ListenAndServeUNIX when it attempts to remove a pre-existing file at the unix socket path before binding, and os.Remove fails with an error other than not-exist. The server deletes any stale socket file first so it can bind cleanly; an unremovable file blocks startup.

Source

Thrown at server.go:1786

// such as IPv6.
//
// Accepted connections are configured to enable TCP keep-alives.
func (s *Server) ListenAndServe(addr string) error {
	ln, err := net.Listen("tcp4", addr)
	if err != nil {
		return err
	}
	return s.Serve(ln)
}

// ListenAndServeUNIX serves HTTP requests from the given UNIX addr.
//
// The function deletes existing file at addr before starting serving.
//
// The server sets the given file mode for the UNIX addr.
func (s *Server) ListenAndServeUNIX(addr string, mode os.FileMode) error {
	if err := os.Remove(addr); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("unexpected error when trying to remove unix socket file %q: %w", addr, err)
	}
	ln, err := net.Listen("unix", addr)
	if err != nil {
		return err
	}
	if err = os.Chmod(addr, mode); err != nil {
		// Close the listener so the unix socket file descriptor is not
		// leaked when chmod fails before Serve takes ownership of it.
		_ = ln.Close()
		return fmt.Errorf("cannot chmod %#o for %q: %w", mode, addr, err)
	}
	return s.Serve(ln)
}

// ListenAndServeTLS serves HTTPS requests from the given TCP4 addr.
//
// certFile and keyFile are paths to TLS certificate and key files.
//

View on GitHub (pinned to c96f600972)

Solutions

  1. Manually remove the stale socket file (rm /path/to.sock) or fix its permissions so the server user can delete it.
  2. Run the server with a user that has write+execute permission on the socket's parent directory.
  3. Move the socket path to an app-owned directory (e.g. /run/myapp/app.sock with proper tmpfiles.d setup).
  4. Ensure the path is not a directory and previous instances ran under the same UID.

Example fix

// before
app.ListenAndServeUNIX("/var/run/app.sock", 0o600) // /var/run is root-only
// after
os.MkdirAll("/run/app", 0o755)
app.ListenAndServeUNIX("/run/app/app.sock", 0o600)
Defensive patterns

Strategy: try-catch

Validate before calling

// Before ListenAndServeUNIX, check the path is removable
if fi, err := os.Lstat(addr); err == nil {
    if fi.IsDir() { log.Fatalf("%s is a directory", addr) }
    if err := os.Remove(addr); err != nil && !os.IsNotExist(err) {
        log.Fatalf("cannot remove stale socket %s: %v", addr, err)
    }
}

Try / catch

err := app.ListenAndServeUNIX(sockPath, 0o600)
if err != nil && strings.Contains(err.Error(), "remove unix socket") {
    log.Fatalf("fix permissions on %s or remove stale socket: %v", filepath.Dir(sockPath), err)
}

Prevention

When it happens

Trigger: The path at addr exists and cannot be removed: it is a directory, permission is denied on the parent directory, or the file is owned by another user without write access to the directory. Any os.Remove error that is not ENOENT triggers this.

Common situations: Stale socket left by a previous run under a different user/UID (e.g. container ran as root previously, now as non-root); socket path placed in a read-only or root-owned directory; a regular directory accidentally configured as the unix socket path.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/fa7afdee4407c565. Report an issue: GitHub.