slackhq/nebula · error
Read failed: %w
Error message
Read failed: %w
What it means
Catch-all wrapping error at the end of NativeTun.Read's switch: ReceivePacket returned an error other than the handled cases (ERROR_NO_MORE_ITEMS, ERROR_HANDLE_EOF, ERROR_INVALID_DATA). An unexpected Wintun driver error on read; preserved with %w. Handled cases exit earlier, so reaching this line is abnormal.
Source
Thrown at wintun/tun.go:148
case nil:
packetSize := len(packet)
copy(buff[offset:], packet)
tun.session.ReleaseReceivePacket(packet)
tun.rate.update(uint64(packetSize))
return packetSize, nil
case windows.ERROR_NO_MORE_ITEMS:
if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration {
windows.WaitForSingleObject(tun.readWait, windows.INFINITE)
goto retry
}
procyield(1)
continue
case windows.ERROR_HANDLE_EOF:
return 0, os.ErrClosed
case windows.ERROR_INVALID_DATA:
return 0, errors.New("Send ring corrupt")
}
return 0, fmt.Errorf("Read failed: %w", err)
}
}
func (tun *NativeTun) Flush() error {
return nil
}
func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
tun.running.Add(1)
defer tun.running.Done()
if atomic.LoadInt32(&tun.close) == 1 {
return 0, os.ErrClosed
}
packetSize := len(buff) - offset
tun.rate.update(uint64(packetSize))
packet, err := tun.session.AllocateSendPacket(packetSize)View on GitHub (pinned to dd8f660c0a)
Solutions
- Retry the read — transient driver errors often clear
- Recreate the TUN device if the error persists
- Report the wrapped Windows error code to diagnose the driver state
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at wintun/tun.go:148 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/c5637baa769f8462.
Report an issue: GitHub.