{"record":{"id":"40b2b34fbf1c3b3b","repo":"k3s-io/k3s","slug":"apiserver-not-ready","errorCode":null,"errorMessage":"apiserver not ready","messagePattern":"apiserver not ready","errorType":"http","errorClass":null,"httpStatus":503,"severity":"warning","filePath":"pkg/util/apierrors.go","lineNumber":18,"sourceCode":"package util\n\nimport (\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net/http\"\n\n\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}","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/util/apierrors.go#L1-L36","documentation":"ErrAPINotReady (pkg/util/apierrors.go) is sent as HTTP 503 by handlers.APIServer when a request to the proxied kube-apiserver routes (/k8s/... on the supervisor port) arrives but control.Runtime.APIServer is nil - the apiserver handler has not been installed yet. It marks the startup window or a failed apiserver launch, and util.IsAPIServerError treats it (and ErrAPIDisabled) specially for retry logic.","triggerScenarios":"Hitting the supervisor's apiserver proxy route before kube-apiserver finished initializing, or after apiserver startup failed so Runtime.APIServer was never set. Agents and clients using the supervisor port as their kube-apiserver endpoint see this during early startup.","commonSituations":"Scripts that target 6443 immediately after k3s starts; first-boot joins; control planes slow under load (etcd compaction, disk pressure) so apiserver init takes minutes.","solutions":["Retry with backoff until /readyz (or the supervisor's readyz route) succeeds - this error is expected to be transient.","If it persists, check k3s logs for kube-apiserver startup failures (bad --kube-apiserver-arg, cert problems, etcd unavailable).","Point clients at a load balancer that health-checks /readyz so unready servers are skipped.","Verify disk/CPU headroom on the server; slow etcd delays apiserver readiness."],"exampleFix":"# before: one-shot call may hit 503 apiserver not ready\ncurl -sk https://127.0.0.1:6443/k8s/version\n\n# after: gate on readiness\nuntil curl -sk https://127.0.0.1:6443/readyz >/dev/null; do sleep 2; done\ncurl -sk https://127.0.0.1:6443/k8s/version","handlingStrategy":"retry","validationCode":"# Gate any /k8s call on readiness first\nuntil curl -sk https://127.0.0.1:6443/readyz >/dev/null 2>&1; do sleep 2; done","typeGuard":null,"tryCatchPattern":"if errors.Is(err, util.ErrAPINotReady) || resp.StatusCode == http.StatusServiceUnavailable {\n    // startup window: retry with backoff; escalate only after readyz stays green and calls still fail\n}","preventionTips":["In Go clients, use util.IsAPIServerError-style checks (errors.Is against ErrAPINotReady) to classify 503s.","Front supervisors with an LB health-checked on /readyz.","Give slow control planes minutes, not seconds, before declaring failure."],"tags":["k3s","apiserver","startup","transient","http-503"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}