kataras/iris · error
%s: %w
Error message
%s: %w
What it means
netutil.UNIX removes any existing socket file before listening; if os.Remove fails with an error other than "not exist" (e.g. permission denied, path is a directory), the error is wrapped with the socket path and returned.
Source
Thrown at core/netutil/tcp.go:71
func TCPKeepAlive(addr string, reuse bool, keepAliveDur time.Duration) (ln net.Listener, err error) {
// if strings.HasPrefix(addr, "127.0.0.1") {
// // it's ipv4, use ipv4 tcp listener instead of the default ipv6. Don't.
// ln, err = net.Listen("tcp4", addr)
// } else {
// ln, err = TCP(addr)
// }
ln, err = TCP(addr, reuse)
if err != nil {
return nil, err
}
return tcpKeepAliveListener{ln.(*net.TCPListener), keepAliveDur}, nil
}
// UNIX returns a new unix(file) Listener.
func UNIX(socketFile string, mode os.FileMode) (net.Listener, error) {
if errOs := os.Remove(socketFile); errOs != nil && !os.IsNotExist(errOs) {
return nil, fmt.Errorf("%s: %w", socketFile, errOs)
}
l, err := net.Listen("unix", socketFile)
if err != nil {
return nil, fmt.Errorf("port already in use: %w", err)
}
if err = os.Chmod(socketFile, mode); err != nil {
return nil, fmt.Errorf("cannot chmod %#o for %q: %w", mode, socketFile, err)
}
return l, nil
}
// TLS returns a new TLS Listener and an error on failure.
func TLS(addr, certFile, keyFile string) (net.Listener, error) {
if certFile == "" || keyFile == "" {
return nil, errors.New("empty certFile or KeyFile")View on GitHub (pinned to 7bedaf55a0)
Solutions
- Ensure the directory containing the socket is writable by the process user and that socketFile is not a directory.
- Manually remove the stale socket file before starting, or run under a user that can.
- Point UNIX() to a fresh path in a writable temp/run directory (e.g. /run/myapp/app.sock).
Example fix
// before
ln, _ := netutil.UNIX("/var/run/app.sock", 0666) // permission denied
// after
ln, _ := netutil.UNIX("/run/myapp/app.sock", 0666) // dir owned by app user
Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(socketFile); err == nil && fi.IsDir() {
return errors.New("socket path is a directory")
}
// ensure parent dir is writable
if err := os.MkdirAll(filepath.Dir(socketFile), 0755); err != nil {
return err
} Try / catch
ln, err := netutil.UNIX(socketFile, mode)
if err != nil {
if !os.IsNotExist(err) && strings.Contains(err.Error(), socketFile) {
os.RemoveAll(socketFile) // only if safe
ln, err = netutil.UNIX(socketFile, mode)
}
} Prevention
- Run the process as the same user across restarts
- Point sockets at app-owned dirs like /run/<app>/
- Ensure socketFile is not a directory and the parent is writable
When it happens
Trigger: Calling netutil.UNIX(socketFile, mode) where socketFile exists but cannot be removed: read-only directory, the path is a directory rather than a socket, or another user owns it.
Common situations: Stale socket left by a crashed process owned by another user; pointing socketFile at a directory; running the app as a non-root user after a previous root run.
Related errors
- cannot chmod %#o for %q: %w
- dest directory: %s: eval symlinks: %w
- unexpected "fsOrDir" argument type of %T (string or fs.FS or
- port already in use: %w
- walk: %s: %w
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/cc799dfaf4cbef2f.
Report an issue: GitHub.