Platforms and DevOps

cert-manager Certificate READY False: find the failing step

By · Last verified

Error messageREADY: False Message: Issuing certificate as Secret does not exist

A Certificate stuck at READY False means cert-manager has not obtained a signed certificate yet, and the reason is in one of the resources it created underneath. For ACME issuers such as Let's Encrypt the chain is Certificate → CertificateRequest → Order → Challenge; the first resource in that chain that reports an error is the one to fix.

Quick fix

The Challenge resource usually holds the CA's exact error message.

Walk down the chain in the Certificate's namespace:

kubectl describe certificate example-com -n web
kubectl get certificaterequest,order,challenge -n web
kubectl describe challenge -n web
kubectl describe clusterissuer letsencrypt-prod

The Status and Events of the Challenge usually contain the CA's exact message (for example a 404, a timeout, or a DNS problem). Fix that, then let cert-manager retry or delete the failed CertificateRequest to start over.

Causes

Most stuck Certificates fail at the Challenge: an HTTP-01 path the CA cannot reach, or DNS-01 with wrong credentials or zones.

1. HTTP-01 challenge cannot be reached

The CA must fetch http://<domain>/.well-known/acme-challenge/<token> through your ingress. cert-manager creates a temporary solver pod, Service and Ingress for it.

  • Confirm: the Challenge shows Waiting for HTTP-01 challenge propagation or an error like wrong status code '404'; curl http://example.com/.well-known/acme-challenge/test from outside never reaches the cluster.
  • Fix: make the solver's ingressClassName (or class annotation) match your controller, expose port 80 on the controller's LoadBalancer, and exempt the challenge path from forced HTTPS redirects and authentication middleware. DNS for the name must point at the ingress load balancer.

2. DNS-01 credentials, zone or propagation

  • Confirm: the Challenge reports API errors (403, invalid credentials), NXDOMAIN, or keeps waiting for propagation.
  • Fix: check the Secret referenced by the solver and the provider permissions; make sure the solver targets the zone the domain is delegated to. When the cluster uses split-horizon DNS, configure the controller's --dns01-recursive-nameservers with public resolvers. See NXDOMAIN.

3. Issuer not Ready or referenced wrongly

  • Confirm: kubectl get issuer,clusterissuer -A shows READY False, or the CertificateRequest says the issuer was not found.
  • Fix: an Issuer is namespaced and only serves Certificates in the same namespace; use kind: ClusterIssuer in issuerRef for a cluster-wide issuer. Check the ACME server URL, email and private key Secret.

4. The CA refuses the order

5. Secret or webhook problems

  • Confirm: events mention a conflict with an existing Secret, or the cert-manager webhook is unreachable (failed calling webhook).
  • Fix: make sure only one Certificate manages a given secretName; check that the cert-manager, cainjector and webhook pods are running and that network policies allow the API server to reach the webhook.

Fixes by environment

The failing step is found the same way everywhere; what differs is how the challenge reaches the CA through an ingress, a Gateway or a load balancer.

Ingress-based annotation (cert-manager.io/cluster-issuer): cert-manager's ingress-shim creates the Certificate for you; describe it by the name of the tls.secretName.

Gateway API: HTTP-01 through Gateway API needs the solver configured with gatewayHTTPRoute and a Gateway listener on port 80.

Private clusters and clusters behind NAT: HTTP-01 needs a public route to port 80; otherwise use DNS-01.

Cloud load balancers: health checks or WAF rules on the load balancer can block or redirect challenge requests; exempt the path.

Staging first: a staging ClusterIssuer avoids burning production limits while you debug.

Don't do this

  • Delete and recreate the Certificate in a loop. Each new Order counts toward CA limits; fix the failing step first.
  • Disable HTTPS redirects globally to let the challenge through. Exempt /.well-known/acme-challenge/ only.
  • Copy a certificate into the Secret by hand and leave the Certificate broken. It will not renew, and it will expire silently.

FAQ

How long should a Certificate take to become Ready?

With a working HTTP-01 or DNS-01 setup, usually well under a few minutes; DNS-01 adds the propagation wait. If it is still not Ready after ten minutes, look at the Challenge resources rather than waiting longer.

How do I force cert-manager to retry?

cert-manager retries failed requests with a back-off. After fixing the cause you can delete the failed CertificateRequest so a new one is created, or use the cmctl tool (cmctl renew <certificate>) to trigger issuance.

Should I test with the Let's Encrypt staging server?

Yes. Create a separate ClusterIssuer pointing at https://acme-staging-v02.api.letsencrypt.org/directory and switch the Certificate's issuerRef to the production issuer only after it becomes Ready. Failed production attempts count toward rate limits.

Sources

  1. cert-manager: Troubleshooting
  2. cert-manager: Troubleshooting Problems with ACME / Let's Encrypt Certificates
  3. cert-manager: Certificate resource
  4. cert-manager: ACME issuer configuration
  5. Let's Encrypt: Rate Limits