netbirdio/netbird · warning
failed handling request
Error message
failed handling request
What it means
WriteErrorResponse has already written the HTTP status and Content-Type when json.Encode of the ErrorResponse body fails. The fallback http.Error cannot change the status line anymore, so the client receives the intended status with a truncated or empty body. The usual cause is the client disconnecting while the error response was being written, not a server fault. The original handler error was already logged by WriteError before this point.
Source
Thrown at shared/management/http/util/util.go:78
if err != nil {
return err
}
return nil
default:
return errors.New("invalid duration")
}
}
// WriteErrorResponse prepares and writes an error response i nJSON
func WriteErrorResponse(errMsg string, httpStatus int, w http.ResponseWriter) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(httpStatus)
err := json.NewEncoder(w).Encode(&ErrorResponse{
Message: errMsg,
Code: httpStatus,
})
if err != nil {
http.Error(w, "failed handling request", http.StatusInternalServerError)
}
}
// WriteError converts an error to an JSON error response.
// If it is known internal error of type server.Error then it sets the messages from the error, a generic message otherwise
func WriteError(ctx context.Context, err error, w http.ResponseWriter) {
log.WithContext(ctx).Errorf("got a handler error: %s", err.Error())
errStatus, ok := status.FromError(err)
httpStatus := http.StatusInternalServerError
msg := "internal server error"
if ok {
switch errStatus.Type() {
case status.UserAlreadyExists:
httpStatus = http.StatusConflict
case status.AlreadyExists:
httpStatus = http.StatusConflict
case status.PreconditionFailed:
httpStatus = http.StatusPreconditionFailedView on GitHub (pinned to 93e97f4bf1)
Solutions
- Match against the server logs: the real handler error was logged by WriteError before this fallback fired
- Raise or remove short client timeouts for management API calls
- Retry the request if it is idempotent; the disconnect does not imply the operation failed
- If it reproduces on a stable connection, investigate response size or proxying in between
Defensive patterns
Strategy: retry
Try / catch
resp, err := doManagementCall(req)
if err == nil && resp.StatusCode >= 500 {
body, rerr := io.ReadAll(resp.Body)
if rerr != nil || len(body) == 0 {
// the error response itself failed to encode (client disconnect);
// the server already logged the real cause. Retry idempotent calls with backoff.
}
} Prevention
- Give management API clients generous timeouts instead of aborting mid-response
- When a 5xx body is empty, check server logs for 'got a handler error' before assuming server fault
- Make management API operations idempotent where possible so disconnects are safely retryable
When it happens
Trigger: A management REST handler returns an error and the client aborts the connection (timeout, cancel, navigation) before the JSON error body is fully encoded.
Common situations: Aggressive client-side timeouts in CLI or API scripts; browsers cancelling in-flight requests; load balancers cutting slow responses.
Related errors
- %s %s
- Run `netbird profile list --show-id` to see IDs, then selec
- service domain is required
- getting a request OAuth flow info failed: %v
- host argument required
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/cbf6f59d4a3bcd71.
Report an issue: GitHub.