cert-manager
Let's Encrypt
SSL certificate
certificate issue
Kubernetes

Certificate issued by cert manager reads as issued by cert-manager.local instead of Let's Encrypt and does not work

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If a Kubernetes certificate shows Issued By: cert-manager.local instead of Let's Encrypt, the certificate being served is not the public ACME certificate you expected. In practice, that usually means cert-manager issued a self-signed temporary or internal certificate because the Let's Encrypt flow did not complete, or because the wrong issuer or secret is wired into the ingress.

What cert-manager.local Usually Means

cert-manager can manage certificates from different issuer types, including self-signed issuers, private CAs, and ACME issuers such as Let's Encrypt. If the presented certificate says cert-manager.local, cert-manager itself is the issuer rather than Let's Encrypt.

That usually points to one of these situations:

  • the issuerRef does not point to the expected ACME issuer
  • ACME validation failed, so the final certificate was never issued
  • a temporary self-signed certificate is still in the secret
  • the ingress is serving the wrong TLS secret

The cert-manager documentation also notes that temporary self-signed certificates can be created during issuance when cert-manager.io/issue-temporary-certificate: "true" is in play, including through some ingress annotations.

Verify the Issuer First

A working Let's Encrypt issuer should reference the ACME production endpoint.

yaml
1apiVersion: cert-manager.io/v1
2kind: ClusterIssuer
3metadata:
4  name: letsencrypt-prod
5spec:
6  acme:
7    email: [email protected]
8    server: https://acme-v02.api.letsencrypt.org/directory
9    privateKeySecretRef:
10      name: letsencrypt-prod-account-key
11    solvers:
12      - http01:
13          ingress:
14            class: nginx

Then the certificate should point to that issuer explicitly.

yaml
1apiVersion: cert-manager.io/v1
2kind: Certificate
3metadata:
4  name: app-cert
5  namespace: app
6spec:
7  secretName: app-tls
8  dnsNames:
9    - app.example.com
10  issuerRef:
11    name: letsencrypt-prod
12    kind: ClusterIssuer

If issuerRef points to a self-signed or CA issuer, cert-manager will never contact Let's Encrypt.

Follow the ACME Resource Chain

Do not stop at the Certificate object. cert-manager expresses the issuance state across several resources.

bash
1kubectl describe certificate app-cert -n app
2kubectl get certificaterequests -n app
3kubectl get orders.acme.cert-manager.io -n app
4kubectl get challenges.acme.cert-manager.io -n app

If the ACME order or challenge failed, one of these resources usually contains the real reason. Common causes are DNS records pointing to the wrong address, an ingress class mismatch, or HTTP-01 challenge traffic never reaching the solver.

Confirm the Secret Actually Served

Even if cert-manager issued the correct certificate, the ingress might still be serving an older or different secret.

bash
kubectl describe ingress app-ingress -n app
kubectl get secret app-tls -n app -o jsonpath='{.data.tls\.crt}' | base64 --decode | openssl x509 -noout -issuer -subject

That second command tells you what certificate is really inside the secret, which is much more reliable than guessing from browser behavior.

Temporary Certificates Can Stay Around

Temporary certificates are supposed to be placeholders until the signed certificate arrives. If cert-manager.local persists, that means the ACME path is still broken or the wrong secret is being used. Treat it as an unresolved issuance problem, not as a cosmetic oddity.

Common Pitfalls

The most common mistake is assuming cert-manager.local is just another name for Let's Encrypt. It is not. It identifies a cert-manager-issued certificate.

Another mistake is repeatedly reapplying manifests without inspecting CertificateRequest, Order, and Challenge. Those resources usually tell you exactly why issuance failed.

Teams also often verify the Certificate resource but forget to verify which TLS secret the ingress is actually serving.

Summary

  • 'cert-manager.local means the served certificate is not the Let's Encrypt certificate you expected.'
  • Verify that issuerRef points to the correct ACME Issuer or ClusterIssuer.
  • Inspect CertificateRequest, Order, and Challenge resources for the real failure.
  • Check the TLS secret and ingress wiring, not just the high-level Certificate object.
  • If a temporary certificate remains in use, the ACME issuance flow is still broken.

Course illustration
Course illustration

All Rights Reserved.