Illustrative engineer at a laptop beside a certificate, TXT record and certificate-authority teaching model.

WIUNIX ACADEMY

cert-manager DNS-01 renewal stuck? Trace Certificate, Order and authoritative TXT

Locate renewal failure in the CertificateRequest, ACME Order, solver permission or DNS self-check; verify the served certificate after a controlled retry.

Advanced40 min readUpdated
Make this guide yours

YOUR SYSTEM. YOUR STEPS.

Where are you working?

Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.

Red Hat Enterprise Linux 10Reviewed against official documentation ·

USE YOUR OWN VALUES

Configure this tutorial

Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.

Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.

Set values for my environment12 editable values

THE OUTCOME

What will you have at the end?

Diagnose one existing ACME DNS-01 certificate without deleting TLS Secrets, exposing DNS credentials or blindly forcing repeated orders.

Supported operating systems and versions

Documented existing-cluster diagnosis; no certificate request, DNS write, credential access or production renewal was performed during authoring. The current tutorial form accepts simple identifiers of at most32characters. This is a form limitation, not the Kubernetes resource-name limit. Never truncate or rename a live object to fit. For a longer existing resource/context name, follow this same diagnostic sequence in the operator-owned direct CLI/editor workflow with its exact original name; no silent default substitution.

Before you begin

  • Existing supported cert-manager with ACME DNS-01 and one owned Certificate
  • Read access to CertificateRequest/Order/Challenge and redacted controller logs
  • dig, OpenSSL and supported cmctl for an optional approved retry
  • The current tutorial form accepts simple identifiers of at most32characters. This is a form limitation, not the Kubernetes resource-name limit. Never truncate or rename a live object to fit. For a longer existing resource/context name, follow this same diagnostic sequence in the operator-owned direct CLI/editor workflow with its exact original name; no silent default substitution.
01

LET’S BUILD

Prepare the selected operator host

These are operator-host packages only. Review the transaction before approving; do not install tools inside application containers. The cluster, server and application binaries must already exist with owner-approved versions. Use Bash for the following panels. Package installation changes this selected host but starts no new application server.

Use an existing Linux kubectl within one minor version of every API-server version; inspect the actual server version in the authorized context before proceeding. Do not install kubelet/kubeadm or overwrite cluster client repositories for this diagnosis.

bash

Selected operator host; approved package transaction

sudo dnf install ca-certificates bash coreutils bind-utils openssl
if ! command -v curl >/dev/null 2>&1; then sudo dnf install curl; fi
cat /etc/os-release
command -v bash curl timeout
command -v kubectl
kubectl version --client --output=yaml
dig -v
How do I know it worked?

The OS/version matches the selection, required tools resolve, and existing application/client versions satisfy the stated compatibility boundary. Stop if a binary is missing or incompatible.

Preserve host security and existing paths

Keep SELinux enforcing and firewalld rules in place. These client-side diagnostics require outbound access to the approved API/TLS/SFTP destination; they need no new inbound host port. A failure in a confined systemd service may differ from an interactive shell. Review AVC denials, file labels and service permissions with the policy owner rather than disabling SELinux, broad allow rules or disabling the firewall. Trust-chain/crypto-policy failures require a compatible endpoint, not weakened system crypto. Existing custom data/config paths need their established labels; never run a recursive relabel blindly.

bash

Selected operator host; read-only security inspection

if command -v getenforce >/dev/null 2>&1; then getenforce; fi
if command -v firewall-cmd >/dev/null 2>&1; then firewall-cmd --state; fi

Follow the object chain, not just Ready=False

Certificate describes the desired certificate and Secret. CertificateRequest records a request; an ACME Issuer uses an Order with one or more Challenges. Failure can occur before DNS presentation, during propagation/self-check, at CA validation or after issuance when a consumer still serves an old Secret. Identify the exact layer first.

This is diagnosis of an existing supported cert-manager installation, not installation or a universal DNS provider recipe. DNS API credentials stay in the existing protected Secret mechanism. Never paste Secret values into this page, logs or command arguments.

02

LET’S BUILD

Check certificate identity and renewal timing

Confirm the authorized context and Certificate name. Read conditions, notAfter and renewalTime and the referenced Issuer kind/name. A healthy current certificate can coexist with a failing renewal. The resource name is not necessarily its DNS SAN or TLS Secret name.

bash

Operator terminal; authorized lab context

kubectl config get-contexts 'lab'
kubectl --context='lab' -n 'academy-lab' get certificate 'api-tls' -o yaml
kubectl --context='lab' -n 'academy-lab' describe certificate 'api-tls'
How do I know it worked?

The intended DNS names, Secret, issuer reference and current renewal conditions are known.

03

LET’S BUILD

Select the actual request, Order and Challenge

List the namespace resources and follow ownerReferences from the selected Certificate through the current request. Names in these fields are public identifiers, not credentials. Multiple old requests can exist; choose the one connected to the failed renewal and record its generation/time. Do not delete requests to clear their symptoms.

bash

Operator terminal; authorized lab context

kubectl --context='lab' -n 'academy-lab' get certificaterequest,order,challenge
kubectl --context='lab' -n 'academy-lab' describe certificaterequest 'api-tls-1'
kubectl --context='lab' -n 'academy-lab' describe order 'api-tls-order'
kubectl --context='lab' -n 'academy-lab' describe challenge 'api-tls-challenge'
How do I know it worked?

One linked object chain and a specific failure message/state are captured.

04

LET’S BUILD

Check the issuer at the correct scope

Use the panel matching issuerRef.kind. A namespace Issuer belongs to the Certificate namespace; ClusterIssuer is cluster-scoped and its credential Secret resolution follows cert-manager’s configured cluster-resource namespace. Check Ready, ACME account registration and selected solver zone/selector before touching DNS permissions.

bash

Operator terminal; authorized lab context

# Run only the command matching issuerRef.kind:
kubectl --context='lab' -n 'academy-lab' describe issuer 'letsencrypt'
# OR, for ClusterIssuer:
kubectl --context='lab' describe clusterissuer 'letsencrypt'
How do I know it worked?

Correct issuer scope and its readiness/account/solver status are confirmed.

Explore all tutorials ↗