{"record":{"id":"e4461682ada334bc","repo":"k3s-io/k3s","slug":"s-error-id-05d","errorCode":null,"errorMessage":"%s error ID %05d","messagePattern":"(.+?) error ID %05d","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"pkg/util/apierrors.go","lineNumber":28,"sourceCode":"\t\"github.com/k3s-io/api/pkg/generated/clientset/versioned/scheme\"\n\t\"github.com/sirupsen/logrus\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters\"\n)\n\nvar ErrAPINotReady = errors.New(\"apiserver not ready\")\nvar ErrAPIDisabled = errors.New(\"apiserver disabled\")\nvar ErrCoreNotReady = errors.New(\"runtime core not ready\")\n\n// SendErrorWithID sends and logs a random error ID so that logs can be correlated\n// between the REST API (which does not provide any detailed error output, to avoid\n// information disclosure) and the server logs.\nfunc SendErrorWithID(err error, component string, resp http.ResponseWriter, req *http.Request, status ...int) {\n\terrID, _ := rand.Int(rand.Reader, big.NewInt(99999))\n\tlogrus.Errorf(\"%s error ID %05d: %v\", component, errID, err)\n\tSendError(fmt.Errorf(\"%s error ID %05d\", component, errID), resp, req, status...)\n}\n\n// SendError sends a properly formatted error response\nfunc SendError(err error, resp http.ResponseWriter, req *http.Request, status ...int) {\n\tvar code int\n\tif len(status) == 1 {\n\t\tcode = status[0]\n\t}\n\tif code == 0 || code == http.StatusOK {\n\t\tcode = http.StatusInternalServerError\n\t}\n\n\t// Don't log \"apiserver not ready\" or \"apiserver disabled\" errors, they are frequent during startup\n\tif !errors.Is(err, ErrAPINotReady) && !errors.Is(err, ErrAPIDisabled) {\n\t\tlogrus.Errorf(\"Sending %s %d response to %s: %v\", req.Proto, code, req.RemoteAddr, err)\n\t}\n\n\tvar serr *apierrors.StatusError","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/util/apierrors.go#L10-L46","documentation":"SendErrorWithID generates a random 5-digit ID, logs the real error server-side ('<component> error ID 01234: <detail>'), and sends the client only '<component> error ID 01234' with HTTP 500 unless an explicit status was passed. The design avoids information disclosure: the REST response carries no stack or detail, but the ID correlates it to the server log entry containing the root cause.","triggerScenarios":"Any handler using SendErrorWithID hitting an internal failure, e.g. the apiserver/runtime core not yet ready, etcd unavailability, or an unexpected error while processing the request.","commonSituations":"Hitting the REST API while the embedded control plane is still booting; transient etcd/apiserver unavailability; handler bugs surfacing as opaque 500s that confuse users because the body has no detail.","solutions":["Take the exact ID from the HTTP body and grep the server logs for it (journalctl, kubectl logs, or container logs) to see the underlying error","If it occurs right after startup, wait for the apiserver/runtime core to become ready and retry","If persistent, fix the root cause shown in the log line (config, certificates, connectivity) - not the wrapper","If you operate the client, log the error ID in your own logs/support bundle for correlation with the server"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"var errIDRe = regexp.MustCompile(`error ID (\\d{5})`)\n\nfunc extractErrorID(body string) (string, bool) {\n\tm := errIDRe.FindStringSubmatch(body)\n\tif m == nil {\n\t\treturn \"\", false\n\t}\n\treturn m[1], true\n}","tryCatchPattern":"resp, err := client.Do(req)\nif err != nil {\n\treturn err\n}\ndefer resp.Body.Close()\nbody, _ := io.ReadAll(resp.Body)\nif resp.StatusCode == http.StatusInternalServerError {\n\tif id, ok := extractErrorID(string(body)); ok {\n\t\tlog.Printf(\"server error %s: correlate with server log 'error ID %s'\", resp.Status, id)\n\t}\n\t// internal errors may be transient (startup, etcd blip): retry with backoff\n\treturn retryWithBackoff(req)\n}","preventionTips":["Log the 5-digit error ID client-side immediately; it is the only correlation to server logs","Retry with backoff on these 500s - many are startup or etcd transients","Centralize server logs so the 'error ID NNNNN: detail' line can be found later","Wait for readiness endpoints before first API calls after service startup"],"tags":["go","http","api","logging","correlation"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}