gofiber/fiber · 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
Emitted by createListener when ListenerNetwork is 'unix' and os.Remove of the configured socket path returns an error other than os.ErrNotExist. Fiber proactively clears a stale socket before binding so a crashed/restarting process can re-claim the address; any removal error that is NOT 'file does not exist' is treated as fatal because the subsequent net.Listen would almost certainly fail too. The wrapped %w preserves the underlying syscall error (EACCES, EISDIR, EBUSY, etc.).
Source
Thrown at listen.go:373
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 9a4c7e57fe)
Solutions
- Identify and stop the prior holder: 'lsof <path>' or 'fuser <path>' then kill the PID, or stop the systemd unit.
- Fix ownership/permissions so the current process can remove the file: 'sudo chown $(id -u):$(id -g) <path>' or 'sudo rm <path>'.
- Verify the path is a file/socket and not a directory: 'ls -ld <path>' — if 'd', pick a different path.
- Ensure the parent directory is writable and not on a read-only mount: 'touch <parent>/__t && rm <parent>/__t'.
- Restart the service so createListener can os.Remove cleanly.
Example fix
// before: stale root-owned socket blocks the non-root restart
_ = app.Listen("/var/run/app.sock", fiber.ListenConfig{
ListenerNetwork: fiber.NetworkUnix,
})
// after: own and clean the path before start, or use a runtime-writable dir
os.Remove("/run/user/app/app.sock") // best-effort; ignore IsNotExist
_ = app.Listen("/run/user/app/app.sock", fiber.ListenConfig{
ListenerNetwork: fiber.NetworkUnix,
UnixSocketFileMode: 0o660,
}) Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: ensure the socket path is clearable by this process.
func preflightUnixSocket(path string) error {
abs, err := filepath.Abs(path)
if err != nil {
return err
}
if info, err := os.Stat(abs); err == nil {
if info.IsDir() {
return fmt.Errorf("socket path %q is a directory", abs)
}
if err := os.Remove(abs); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("cannot remove stale socket %q: %w", abs, err)
}
} else if !os.IsNotExist(err) {
return err
}
// parent dir must be writable
return os.MkdirAll(filepath.Dir(abs), 0o755)
} Type guard
null
Try / catch
err := app.Listen(sock, fiber.ListenConfig{ListenerNetwork: fiber.NetworkUnix})
if err != nil {
var lp *net.OpError
if errors.As(err, &lp) && strings.Contains(err.Error(), "remove unix socket") {
// surface as a deployment/permission issue, not a code bug
log.Errorf("socket pre-clear failed (%v) — check owner/perms of %s", err, sock)
}
return err
} Prevention
- Run the process as the user that owns the socket directory or grant it ownership.
- Place unix sockets under a per-app writable dir like /var/lib/<app> or /run/user/<uid>.
- Ensure only one instance binds a given socket path; coordinate via a PID/lock file.
- Avoid read-only mounts for socket paths; verify with a pre-start write test.
When it happens
Trigger: Starting Fiber with app.Listen(NetworkUnix+'/var/run/app.sock', ...) where the path exists and is owned by another uid (EACCES), is a directory (EISDIR), or is held open by a still-running process you don't have permission to unlink. Removing a path on a read-only filesystem or in a directory without write permission also triggers it.
Common situations: Two instances pointed at the same socket where the second lacks privileges; running under a non-root user while the prior run was root (root-owned socket); systemd socket activation leaves a socket file; Docker volume mounted read-only; path typo resolves to an existing directory.
Related errors
- cannot chmod %#o for %q: %w
- open file error: %w
- failed to check directory: %w
- failed to create directory: %w
- failed to create file: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/5ab24ffa8733ca8a.json.
Report an issue: GitHub.