k8s-api-troubleshooting
Skill36 starsChanged 15 days agoApache-2.0View on GitHub
Use when the Kubernetes API server itself refuses or fails a request, before any controller acts on it: "failed calling webhook", "admission webhook ... denied the request", "ValidatingAdmissionPolicy ... denied request", a ReplicaSet with FailedCreate and no pods, an APIService "False (ServiceNotFound)", "FailedDiscoveryCheck" or "MissingEndpoints", "unable to retrieve the complete list of server APIs", a namespace stuck in Terminating, "no matches for kind" or "ensure CRDs are installed first", "strict decoding error: unknown field", a conversion webhook failure, "You must be logged in to the server (Unauthorized)", 429 "too many requests", "etcdserver:" errors, "Request entity too large" or "metadata.annotations: Too long". Investigates with kubectl get, describe, events and the health endpoints, and proposes fixes. Reads first and asks before changing anything.
In this repository31 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- k8s-aks-troubleshootingSkill
- k8s-argocd-troubleshootingSkill
- k8s-autoscaling-troubleshootingSkill
- k8s-cert-manager-troubleshootingSkill
- k8s-cilium-troubleshootingSkill
- k8s-cloudnative-pg-troubleshootingSkill
- k8s-coredns-troubleshootingSkill
- k8s-envoy-gateway-troubleshootingSkill
- k8s-envoy-troubleshootingSkill
- k8s-external-secrets-troubleshootingSkill
- k8s-fluent-bit-troubleshootingSkill
- k8s-flux-troubleshootingSkill
- k8s-gatekeeper-troubleshootingSkill
- k8s-gateway-api-troubleshootingSkill
- k8s-grafana-troubleshootingSkill
- k8s-helm-troubleshootingSkill
- k8s-istio-troubleshootingSkill
- k8s-kyverno-troubleshootingSkill
- k8s-loki-troubleshootingSkill
- k8s-network-troubleshootingSkill
- k8s-node-troubleshootingSkill
- k8s-opentelemetry-collector-troubleshootingSkill
- k8s-prometheus-troubleshootingSkill
- k8s-rbac-troubleshootingSkill
- k8s-storage-troubleshootingSkill
- k8s-triageSkill
- k8s-upgrade-readinessSkill
- k8s-velero-troubleshootingSkill
- k8s-workload-troubleshootingSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 3 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 28
Every request goes through the same steps in the API server: authentication (who is asking: a 401 if nobody), authorization (may they: a …
- Very specific: line 40
Never read Secrets. The built-in view role cannot read webhook configurations, admission policies, APIServices, CRDs or FlowSchemas.
- Distinctive: line 191
If the webhook is no longer wanted, or must let requests through while it is fixed (its checks stop until it is restored):
- Distinctive: line 201
If an aggregated API is no longer used, remove its registration.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
API server troubleshooting
Find out why the API server refuses or fails a request, and propose a fix. Read first, ask before changing. Run the investigation commands freely. Run a command under an "Ask first" line only after the user approves that exact command; if your credentials do not allow it, give it to the user to run. Never run a "Proposed fix"; hand it to the user.
Every request goes through the same steps in the API server: authentication (who is
asking: a 401 if nobody), authorization (may they: a 403 from RBAC), admission
(mutating webhooks, schema validation, then ValidatingAdmissionPolicies and validating
webhooks), then storage in etcd. Requests for an aggregated API (an APIService
such as v1beta1.metrics.k8s.io) are sent on to another server instead, and
discovery lists every group and version, including those. A failure at any step comes
back to the caller, so the error message usually names the step: the webhook, the
APIService, the kind and version, or the limit.
The commands use placeholders: my-namespace, my-app, my-webhook (a webhook
configuration and its Service in my-webhook-system), v1beta1.my-api.example.com (an
APIService) and widgets.my-api.example.com (a CRD). Replace them with the real names.
Never read Secrets. The built-in view role cannot read webhook configurations,
admission policies, APIServices, CRDs or FlowSchemas; if they are forbidden, say so, ask
the user for them, and work from the error text, which already names the webhook, the
group and version, or the APIService.
When to use
- A Deployment, Job or ReplicaSet has no pods and its events say
FailedCreate. - kubectl apply, a CI job, Helm, Argo CD or Flux fails with an error from the server that is not a 403.
- A namespace or another object stays in
Terminating. - kubectl prints warnings about API groups, or the cluster is slow and requests time out.
Hand-offs, by skill name. When the evidence points elsewhere, continue with that skill; if it is not installed, keep going with the steps here and tell the user which skill would help:
Forbidden: User "..." cannot ...(RBAC):k8s-rbac-troubleshooting.- The webhook or policy belongs to Kyverno, Gatekeeper or cert-manager (its name or its
Service says so):
k8s-kyverno-troubleshooting,k8s-gatekeeper-troubleshooting,k8s-cert-manager-troubleshooting. A denial from Istio's or another tool's webhook goes to that tool's skill. v1beta1.metrics.k8s.ioorexternal.metrics.k8s.iounavailable:k8s-autoscaling-troubleshooting.violates PodSecurity, or pods that are created but fail:k8s-workload-troubleshooting.- Helm's own errors (
another operation is in progress, ownership):k8s-helm-troubleshooting.
Investigate
Work through the steps in order. Stop when you have the cause and its evidence.
1. Read the exact error: where the request came from (a controller's events, a Job's log, the user's command) and its full text. A controller retries, so its events show the same message many times.
kubectl get events -n my-namespace --sort-by=.lastTimestamp
kubectl get deployment,replicaset -n my-namespace
kubectl describe replicaset -n my-namespace -l app=my-app
kubectl logs -n my-namespace job/my-deploy --tail=502. Check the API server's health. Everyone, even without RBAC rights, may read these;
[-]... failed names a failing check.
kubectl get --raw '/readyz?verbose'
kubectl get --raw '/livez?verbose'
kubectl version3. Check the aggregated APIs. Any line that is not True is an API that discovery,
namespace deletion and garbage collection cannot reach.
kubectl get apiservices
kubectl get apiservice v1beta1.my-api.example.com -o jsonpath='{.spec.service.namespace}/{.spec.service.name}:{.spec.service.port}{"\n"}{range .status.conditions[*]}{.type}={.status} {.reason}: {.message}{"\n"}{end}'4. Find the webhook named in the error, if there is one. The quoted name is the
webhook's own name (webhooks[].name), not its configuration's; list both to match them.
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
kubectl get validatingwebhookconfigurations -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .webhooks[*]}{" "}{.name}{" policy="}{.failurePolicy}{" timeout="}{.timeoutSeconds}{" svc="}{.clientConfig.service.namespace}{"/"}{.clientConfig.service.name}{" url="}{.clientConfig.url}{"\n"}{end}{end}'
kubectl get mutatingwebhookconfigurations -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .webhooks[*]}{" "}{.name}{" policy="}{.failurePolicy}{" timeout="}{.timeoutSeconds}{" svc="}{.clientConfig.service.namespace}{"/"}{.clientConfig.service.name}{" url="}{.clientConfig.url}{"\n"}{end}{end}'5. For a stuck namespace, read its conditions: they name what blocks it.
kubectl get namespace my-namespace -o jsonpath='{.status.phase}{"\n"}{range .status.conditions[*]}{.type}={.status} {.reason}: {.message}{"\n"}{end}'6. Open the matching reference and follow its steps:
| What you see | Reference |
failed calling webhook, denied the request, a ValidatingAdmissionPolicy, FailedCreate with no pods | references/admission.md |
An APIService not True, discovery errors, no matches for kind, unknown fields, CRD versions and conversion, Terminating that never ends | references/discovery-crds-deletion.md |
401, 429, timeouts, etcdserver: errors, size limits, a failing /readyz | references/auth-load-storage.md |
Read the results
What the common findings mean (Kubernetes 1.37):
Internal error occurred: failed calling webhook "<name>": failed to call webhook: Post "https://<service>.<namespace>.svc:443/<path>?timeout=<n>s": <cause>: the API server could not reach a webhook whosefailurePolicyisFail(the default), so it refused the request. The cause names why:service "..." not found;connect: connection refusedwhen the Service has no ready endpoints;context deadline exceededfor a slow webhook;x509: ...for a wrongcaBundle. A Deployment is still created when only pods are matched: its ReplicaSet shows the error asFailedCreate.admission webhook "<name>" denied the request: ...orValidatingAdmissionPolicy '<policy>' with binding '<binding>' denied request: ...: the check ran and said no. That is a policy decision, not an outage; the message says which rule.- An APIService
False (ServiceNotFound),False (MissingEndpoints)orFalse (FailedDiscoveryCheck): its backend is gone, has no ready pods, or answers badly. Its group's resources cannot be used, and every namespace deletion in the cluster waits for it. - A namespace in
TerminatingwithNamespaceDeletionDiscoveryFailure=True(Discovery failed for some groups, 1 failing: unable to retrieve the complete list of server APIs: <group/version>: stale GroupVersion discovery: ...): an unavailable APIService. WithNamespaceContentRemainingorNamespaceFinalizersRemaining, objects with finalizers are still waiting for their controller. no matches for kind "<Kind>" in version "<group/version>"andensure CRDs are installed first: the API server serves no such kind in that version. Either the CRD is not installed, or it is and that version isserved: falseor was removed; read the CRD's versions before you believe the hint.strict decoding error: unknown field "spec.foo": the field does not exist in that version's schema (often a typo, or a field from a newer version).You must be logged in to the server (Unauthorized): the credentials are missing, expired or for another cluster; 403s are RBAC, not this.the server has received too many requests(429): API Priority and Fairness rejected the request; some client is sending too many.etcdserver: ...,Request entity too large: limit is 3145728ormetadata.annotations: Too long: may not be more than 262144 bytes: storage or size limits; the third is usually a client-side kubectl apply storing a large object in its last-applied annotation.
State the cause in one sentence, then the evidence you saw (the exact message, the webhook, APIService or CRD fields, the namespace conditions), then the proposed fix.
Proposed fix
Show each fix to the user before running it: what it changes and how to undo it.
Webhook configurations, admission policies, APIServices, CRDs and API Priority and
Fairness objects act on the whole cluster: never change or delete them yourself; hand
them to the user as proposed fixes. Prefer the fix that restores the broken part (the
webhook's or the API's backend) over one that turns a check off. Never remove
finalizers by hand or force a namespace's deletion through /finalize: that skips the
cleanup and leaves objects behind. Save an object before a fix changes it, so the undo
can restore it:
kubectl get validatingwebhookconfiguration my-webhook -o yaml
kubectl get apiservice v1beta1.my-api.example.com -o yamlBring a webhook's or an aggregated API's backend back, when it was scaled down. Note
its current replica count first (kubectl get deployment my-webhook -n
my-webhook-system), so the undo puts that number back:
Ask first: the agent runs this only after the user approves it.
kubectl scale deployment my-webhook -n my-webhook-system --replicas=2
# Undo: kubectl scale deployment my-webhook -n my-webhook-system --replicas=0 (the count you noted)If the webhook is no longer wanted, or must let requests through while it is fixed (its checks stop until it is restored):
Proposed fix: review before running. The agent does not run this.
kubectl patch validatingwebhookconfiguration my-webhook --type=json -p '[{"op": "replace", "path": "/webhooks/0/failurePolicy", "value": "Ignore"}]'
# Undo: kubectl apply -f my-webhook-before.yaml (the configuration you saved above)If an aggregated API is no longer used, remove its registration; namespaces then finish deleting on their own:
Proposed fix: review before running. The agent does not run this.
kubectl delete apiservice v1beta1.my-api.example.com
# Undo: kubectl apply -f my-apiservice-before.yaml (the APIService you saved above)Fix a manifest that uses an unserved version or unknown fields in its source (the chart,
the Git repository), then let its pipeline apply it again. Do not test it with
--dry-run=server yourself: that is still an apply, sent through admission and its
webhooks; give it to the user to run.
Sources
Checked against the Kubernetes 1.37 documentation and source (v1.37.1):
- Dynamic admission control, admission webhook good practices, ValidatingAdmissionPolicy and manifest-based admission control.
- The aggregation layer and configuring it.
- CustomResourceDefinitions, CRD versions, field validation and the deprecated API migration guide.
- Finalizers, namespaces and garbage collection.
- Authenticating, API Priority and Fairness, debugging it, health endpoints and operating etcd.
- Messages from the source:
webhook dispatcher,
APIService availability,
namespace deletion conditions
and default roles
(who may read
/readyzand/livez). The webhook, APIService, namespace and CRD messages quoted here were seen on a Kubernetes 1.37 kind cluster.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

