tailscale/tailscale · error
upload failed: %w
Error message
upload failed: %w
What it means
In a server-side upload test (the client downloads), conn.Write failed, so the server could not push test data (net/speedtest/speedtest_server.go:111-116). The %w wraps the write error: broken pipe, connection reset, or i/o timeout — nearly always the client side hanging up early or the path breaking.
Source
Thrown at net/speedtest/speedtest_server.go:115
for {
var n int
var err error
if conf.Direction == Download {
n, err = io.ReadFull(conn, bufferData)
switch err {
case io.EOF, io.ErrUnexpectedEOF:
break SpeedTestLoop
case nil:
// successful read
default:
return nil, fmt.Errorf("unexpected error has occurred: %w", err)
}
} else {
n, err = conn.Write(bufferData)
if err != nil {
// If the write failed, there is most likely something wrong with the connection.
return nil, fmt.Errorf("upload failed: %w", err)
}
}
intervalBytes += n
currentTime = time.Now()
// checks if the current time is more or equal to the lastCalculated time plus the increment
if currentTime.Sub(lastCalculated) >= increment {
results = append(results, Result{Bytes: intervalBytes, IntervalStart: lastCalculated, IntervalEnd: currentTime, Total: false})
lastCalculated = currentTime
totalBytes += intervalBytes
intervalBytes = 0
}
if conf.Direction == Upload && currentTime.Sub(startTime) > conf.TestDuration {
break SpeedTestLoop
}
}
View on GitHub (pinned to 6e0912f979)
Solutions
- Check whether the peer canceled (client-side context) before treating it as an infrastructure error
- Retry the test; one-off resets are common
- Run tailscale ping / check direct-vs-DERP status for the path
- If reproducible on LAN, check MTU and hardware offload (GRO/GSO) on both NICs
- Update both nodes to rule out old client bugs
Defensive patterns
Strategy: retry
Try / catch
if err != nil { // server write path
if errors.Is(err, net.ErrClosed) || errors.Is(err, context.Canceled) {
return err // deliberate shutdown: do not retry
}
// broken pipe / reset while uploading: safe to retry the whole test once
} Prevention
- Keep the client connected for the full TestDuration
- Cancel cleanly (context) rather than killing the process mid-test
- Check MTU/NIC offload settings when writes fail reproducibly on LAN
When it happens
Trigger: Client disconnects or cancels before TestDuration elapses; receiver too slow so buffers fill and the connection stalls out; NAT state expiry dropping the flow.
Common situations: User closes the CLI mid-test; mobile client backgrounds the app; asymmetric MTU or NIC offload issues causing a stall on fast local links.
Related errors
- version mismatch! Server is version %d, client is version %d
- unexpected error has occurred: %w
- errNotUsingTailscale
- tailscale version not found in output
- failed refresh apk repository indexes: %w, output: %s
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/565fa25b1a3d7bbd.
Report an issue: GitHub.