criticalIntermediateSymptom-first#cert-manager#certificates#tls#acme

Certificate stuck in NotReady — issuance failed

kubectl get certificate shows Ready=False

Likely source:availabilityconfiguration

Focused incident mode — strips away everything but this runbook.

Symptoms

  • kubectl get certificate shows Ready=False
  • Ingress serves a stale or self-signed certificate
  • CertificateRequest events show an issuance error

Evidence to grab

Collect these artifacts before you change anything — they prove (or rule out) each cause.

  • Certificate conditions

    kubectl get certificate <CERT-NAME> -n <NAMESPACE> -o yaml
  • Request chain

    kubectl get certificaterequest -n <NAMESPACE> | grep <CERT-NAME>

Diagnostic flow

Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.

Guided decision tree is ready.

Steps with commands, expected output, and pass/fail branches.

Ranked root causes

Evidence checklist

  • Order state failed with an authorization error
  • Challenge events reference ACME 400/429 responses

Confirm before fixing

kubectl get challenges -n <NAMESPACE> -o yaml | grep -A5 reason
READ

Read the challenge failure reason

Fix

kubectl delete certificate <CERT-NAME> -n <NAMESPACE>
DESTRUCTIVE

Delete and recreate after fixing the Issuer/credentials (cert-manager recreates the secret)

Resolution runbook

Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.

1
kubectl describe certificate <CERT-NAME> -n <NAMESPACE> | grep -A10 Conditions
READ

Identify the Ready=False reason

2
kubectl describe challenge -n <NAMESPACE> | tail -30
READ

Read the exact solver failure

3
kubectl get issuer,clusterissuer -n <NAMESPACE>
READ

Confirm the Issuer exists and is Ready

4
kubectl delete certificate <CERT-NAME> -n <NAMESPACE>
DESTRUCTIVE

Recreate the Certificate once the Issuer is healthy

Prevention

  • Monitor the cert-manager metrics certmanager_certificate_ready_status and alert on Ready=0.
  • Set a reasonable renewBefore (e.g. 30d) and keep staging/ACME issuers separate.
  • Version your ClusterIssuer definitions and test DNS credentials in staging first.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.