{"record":{"id":"cbf6f59d4a3bcd71","repo":"netbirdio/netbird","slug":"failed-handling-request","errorCode":null,"errorMessage":"failed handling request","messagePattern":"failed handling request","errorType":"http","errorClass":null,"httpStatus":500,"severity":"warning","filePath":"shared/management/http/util/util.go","lineNumber":78,"sourceCode":"\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn errors.New(\"invalid duration\")\n\t}\n}\n\n// WriteErrorResponse prepares and writes an error response i nJSON\nfunc WriteErrorResponse(errMsg string, httpStatus int, w http.ResponseWriter) {\n\tw.Header().Set(\"Content-Type\", \"application/json; charset=UTF-8\")\n\tw.WriteHeader(httpStatus)\n\terr := json.NewEncoder(w).Encode(&ErrorResponse{\n\t\tMessage: errMsg,\n\t\tCode:    httpStatus,\n\t})\n\tif err != nil {\n\t\thttp.Error(w, \"failed handling request\", http.StatusInternalServerError)\n\t}\n}\n\n// WriteError converts an error to an JSON error response.\n// If it is known internal error of type server.Error then it sets the messages from the error, a generic message otherwise\nfunc WriteError(ctx context.Context, err error, w http.ResponseWriter) {\n\tlog.WithContext(ctx).Errorf(\"got a handler error: %s\", err.Error())\n\terrStatus, ok := status.FromError(err)\n\thttpStatus := http.StatusInternalServerError\n\tmsg := \"internal server error\"\n\tif ok {\n\t\tswitch errStatus.Type() {\n\t\tcase status.UserAlreadyExists:\n\t\t\thttpStatus = http.StatusConflict\n\t\tcase status.AlreadyExists:\n\t\t\thttpStatus = http.StatusConflict\n\t\tcase status.PreconditionFailed:\n\t\t\thttpStatus = http.StatusPreconditionFailed","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/shared/management/http/util/util.go#L60-L96","documentation":"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.","triggerScenarios":"A management REST handler returns an error and the client aborts the connection (timeout, cancel, navigation) before the JSON error body is fully encoded.","commonSituations":"Aggressive client-side timeouts in CLI or API scripts; browsers cancelling in-flight requests; load balancers cutting slow responses.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := doManagementCall(req)\nif err == nil && resp.StatusCode >= 500 {\n    body, rerr := io.ReadAll(resp.Body)\n    if rerr != nil || len(body) == 0 {\n        // the error response itself failed to encode (client disconnect);\n        // the server already logged the real cause. Retry idempotent calls with backoff.\n    }\n}","preventionTips":["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"],"tags":["http","management","rest","client-disconnect","json"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}