lima-vm/lima · info
UDPFileConn connection closed
Error message
UDPFileConn connection closed
What it means
UDPFileConn wraps a net.Conn and its Read first probes the connection by clearing the read deadline; if the underlying connection is already closed, the probe returns net.ErrClosed and Read converts it into the literal error "UDPFileConn connection closed" instead of attempting a read on a dead socket.
Source
Thrown at pkg/networks/usernet/udpfileconn.go:20
// SPDX-License-Identifier: Apache-2.0
package usernet
import (
"errors"
"net"
"time"
)
type UDPFileConn struct {
net.Conn
}
func (conn *UDPFileConn) Read(b []byte) (n int, err error) {
// Check if the connection has been closed
if err := conn.SetReadDeadline(time.Time{}); err != nil {
if errors.Is(err, net.ErrClosed) {
return 0, errors.New("UDPFileConn connection closed")
}
}
return conn.Conn.Read(b)
}
View on GitHub (pinned to dd909d0973)
Solutions
- Treat this error as a normal shutdown signal: break the read loop and return without retrying.
- Synchronize: only call Read while the connection is open; signal readers via a done channel before calling Close().
- Use errors.Is-style comparison or string match on the returned error to detect closure and exit the loop cleanly.
- If you need the underlying net.ErrClosed, check conn.SetReadDeadline yourself before relying on Read.
Example fix
// before
for {
n, err := udpConn.Read(buf)
if err != nil {
log.Fatal(err)
}
}
// after
for {
n, err := udpConn.Read(buf)
if err != nil {
if err.Error() == "UDPFileConn connection closed" || errors.Is(err, net.ErrClosed) {
return nil // graceful shutdown
}
return err
}
} Defensive patterns
Strategy: try-catch
Type guard
function isConnClosed(err) {
return err != null && (err.message === 'UDPFileConn connection closed' ||
(typeof err.unwrap === 'function' && err === null) || /connection closed/i.test(err.message));
} Try / catch
n, err := conn.Read(buf)
if err != nil {
if err.Error() == "UDPFileConn connection closed" || errors.Is(err, net.ErrClosed) {
return nil // expected during shutdown
}
return err
} Prevention
- Close connections only after all reader goroutines have stopped (use a done channel/WaitGroup).
- Treat this error as a graceful-shutdown signal, not a failure.
- Avoid reading from the conn after calling Close in any code path.
- Centralize connection lifecycle ownership in one component.
When it happens
Trigger: A goroutine calls UDPFileConn.Read after the connection's Close() was called (e.g. the usernet daemon shut down or the peer handler closed the socket while a reader loop was still active).
Common situations: Hostagent or guestagent connection handler closing the UDP socket while a relay/packet-reading loop is concurrently blocked on Read; daemon shutdown racing with active connections.
Understand the failure class
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
- expected *net.UDPAddr, got %v
- failed to stop usernet %#q: %w
- usernet unable to resolve IP for SSH forwarding
- failed to kill process with pid %d: %w
- network %#q already exists
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/5ab3d3e010b2f940.
Report an issue: GitHub.