{"record":{"id":"1c3c57d3387da725","repo":"k3s-io/k3s","slug":"apiserver-disabled","errorCode":null,"errorMessage":"apiserver disabled","messagePattern":"apiserver disabled","errorType":"http","errorClass":null,"httpStatus":503,"severity":"info","filePath":"pkg/util/apierrors.go","lineNumber":19,"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}\n\tif code == 0 || code == http.StatusOK {","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/util/apierrors.go#L1-L37","documentation":"ErrAPIDisabled (pkg/util/apierrors.go) is returned as HTTP 503 by handlers.APIServer when the server was started with --disable-api-server (cfg.DisableAPIServer). Such supervisors run agent/dispatcher functions but intentionally host no apiserver, so any request to the proxied /k8s routes is refused permanently on that node.","triggerScenarios":"A kubeconfig or --server URL pointing at a k3s node started with --disable-api-server; probes aimed at a dedicated non-apiserver supervisor in a split control/worker layout.","commonSituations":"HA clusters where api-server duties are split across nodes; clients hardcoded to a node IP instead of the LB/VIP; health checks not updated after a node's role change.","solutions":["Point clients at a server that runs the apiserver (drop --disable-api-server nodes from client endpoints).","Use the load-balanced endpoint/VIP that only includes apiserver-enabled servers.","If the node should serve the API, restart it without --disable-api-server.","Treat 503 'apiserver disabled' as a routing signal: remove the node from the pool, do not retry against it."],"exampleFix":"# before: client pinned to a non-apiserver supervisor\ncurl --cacert ... https://supervisor-noapi:6443/k8s/version   # 503\n\n# after: target apiserver-enabled endpoint (LB)\ncurl --cacert ... https://k3s-api.lb.internal:6443/k8s/version","handlingStrategy":"fallback","validationCode":"# Before pointing a client at a supervisor, confirm it hosts the apiserver\nsystemctl show k3s -p ExecStart | grep -q -- --disable-api-server && echo 'no apiserver here; pick another endpoint'","typeGuard":null,"tryCatchPattern":"if errors.Is(err, util.ErrAPIDisabled) {\n    // permanent for this node: fail over to an apiserver-enabled server; do not retry in place\n}","preventionTips":["Never hardcode client kubeconfigs to a single supervisor IP; use the LB/VIP.","Track which nodes run --disable-api-server and keep them out of client endpoint pools.","Treat 'apiserver disabled' as routing feedback, not an error to retry."],"tags":["k3s","apiserver","configuration","http-503","ha"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}