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

  1. Inspect the path: ls -la <socket-path> and confirm it is a socket (type 's'), not a file/dir.
  2. Run both the previous and current instance under the same user, or chown the parent dir so the runtime user can unlink.
  3. Delete the stale entry manually: rm -f <socket-path>.
  4. If the parent directory is read-only, move the socket to a writable directory and update the addr.
  5. 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

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


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 path

View on GitHub (pinned to a105acad6c)