Release 1.21
These are draft release notes. cert-manager v1.21 is currently a pre-release and is not recommended for use in production. The final release notes will be published when v1.21.0 is released.
cert-manager v1.21 includes:
New features:
- ACME Renewal Information (ARI / RFC 9773) support via the
ACMEUseARIfeature gate - AWS IAM authentication (IRSA, EKS Pod Identity, ambient EC2/ECS) for the Vault issuer
- Modern2026 PKCS#12 encoding profile (FIPS 140-3 compatible)
- Certificate renewal policies
waitInsteadOfSelfChecksolver option — skip cert-manager's self-check for split-horizon DNS or NAT hairpin environments--certificate-request-maximum-backoff-durationflag — cap the exponential retry backoff for failed CertificateRequests- Webhook serving certificate renewal fixed after system suspend or VM live migration
- Venafi OAuth token observability and
AuthFailedIssuer condition; PANW NGTS support added - Gateway API: HTTP01 ListenerSet parentRef fallback annotation; additional listener protocols;
CAInjectorMergingpromoted to GA - cainjector
--ignore-namespacesflag runtimeClassNamesupport for cert-manager components and ACME HTTP01 solver podsstartupapicheck.ttlSecondsAfterFinishedHelm value for automatic Job cleanup--acme-http01-solver-extra-labelsflag to propagateglobal.commonLabelsto solver resources
Breaking changes:
- Removal of the default
tokenrequestRBAC from the Helm chart - Removal of Challenge and Order write permissions from the
cert-manager-editaggregate ClusterRole - Removal of configurable metrics path and port name Helm values
Major Themes
Default tokenrequest RBAC removed from Helm chart
⚠️ Breaking change
The Helm chart no longer creates a default Role and RoleBinding granting
the cert-manager controller permission to create tokens for its own
ServiceAccount (serviceaccounts/token: create).
This RBAC was added in v1.16 (cert-manager/cert-manager#7213) to support a "Using the cert-manager ServiceAccount" section in the Route53 documentation. That docs section was subsequently removed (cert-manager/website#1555) when the Route53 page was restructured, and no documented workflow — Route53 IRSA ambient, Vault Kubernetes auth, or any other issuer — requires the controller to mint tokens for its own ServiceAccount.
If you use serviceAccountRef.name pointing at the controller ServiceAccount,
you must now either:
- create your own
RoleandRoleBindinggrantingserviceaccounts/token: createon that ServiceAccount, or - migrate to a dedicated ServiceAccount with its own RBAC (recommended — see the Vault or Route53 documentation).
Credit to @everping and @kodareef5 for independently identifying (via privately reported security advisories) that this default RBAC widened the trust boundary beyond what cert-manager's published threat model documents.
Restrict Challenge and Order RBAC in cert-manager-edit ClusterRole
⚠️ Potentially breaking change
The cert-manager-edit aggregate ClusterRole no longer grants create for
challenges.acme.cert-manager.io or create, patch, update for
orders.acme.cert-manager.io. This fixes a security issue
(GHSA-8rvj-mm4h-c258)
where these permissions allowed namespace users to bypass Issuer solver
selectors and abuse ClusterIssuer credentials.
These resources are internal to cert-manager's ACME workflow and are not
intended to be created or modified directly by users. Challenge patch and
update are retained because the Challenge spec is immutable after creation
and users may need these verbs to remove stuck finalizers
(cert-manager/cert-manager#3851, cert-manager/cert-manager#3870).
This change was already shipped in patch releases v1.20.3 and v1.19.6, so if you are already running one of those versions this will not be a breaking change.
If you have tooling or workflows that create Challenge or Order resources directly (outside of the normal Certificate → CertificateRequest → Order → Challenge flow), you will need to grant those permissions explicitly.
Metrics port name and path Helm values removed
⚠️ Breaking change
The Helm values prometheus.servicemonitor.targetPort,
prometheus.servicemonitor.path, and prometheus.podmonitor.path have been
removed. The metrics path is always /metrics and the ServiceMonitor
targetPort is always the port named http-metrics — these were the defaults
and there was no supported reason to override them.
The controller Service metrics port has also been renamed from
tcp-prometheus-servicemonitor to http-metrics, aligning it with the webhook
and cainjector services.
Because the Helm values schema uses additionalProperties: false, users who
still have any of the removed keys in their values overrides will see a schema
validation error on upgrade. Remove these keys from your values file before
upgrading.
(cert-manager/cert-manager#8952, @erikgb)
Configurable CertificateRequest retry backoff duration
cert-manager 1.21 adds the --certificate-request-maximum-backoff-duration
controller flag (default: 32 hours), making the exponential backoff cap
configurable alongside the existing --certificate-request-minimum-backoff-duration
flag.
When a CertificateRequest fails, cert-manager backs off exponentially — by
default from 1 hour up to 32 hours. In environments with scheduled CA
maintenance windows, the backoff can grow so large that cert-manager does not
retry until hours after the CA comes back online. With this flag, cluster
operators can lower the ceiling to match their CA's maintenance schedule. For
example, --certificate-request-maximum-backoff-duration=1h ensures that
cert-manager retries at most every hour regardless of how many consecutive
failures have occurred.
The default of 32 hours preserves the behavior of previous releases. The flag
may also be set via the
certificateRequestMaximumBackoffDuration
field in the controller ControllerConfiguration API, or via the Helm chart:
config:certificateRequestMaximumBackoffDuration: 1h
See the controller CLI reference for the full list of flags, and What happens if issuance fails? Will it be retried? for background on how cert-manager retries failed issuances.
(cert-manager/cert-manager#8893, @lunarwhite)
Skip the self-check with waitInsteadOfSelfCheck
cert-manager 1.21 adds the waitInsteadOfSelfCheck solver option for ACME
HTTP01 and DNS01 challenges. When set, cert-manager skips its own self-check
and instead waits the configured duration after presentation before asking the
ACME server to validate. This is an escape hatch for environments where
cert-manager cannot reliably observe the same validation path as the ACME
server, such as split-horizon DNS or NAT loopback (or hairpinning).
See Skip the self-check with
waitInsteadOfSelfCheck
for configuration details.
Webhook Serving Certificate Renewal After System Suspend
The cert-manager webhook generates and automatically renews its own self-signed
serving certificate. Prior to 1.21, the renewal timer relied solely on Go's
monotonic clock (CLOCK_MONOTONIC). During system suspend (S3/S4) or VM live
migration, CLOCK_MONOTONIC stops advancing while wall-clock time
(CLOCK_REALTIME) continues. When the system resumes, the renewal timer has not
yet reached its deadline, so the webhook's serving certificate is never renewed
— even though it has already expired. This causes x509: certificate has expired or is not yet valid errors for all admission and conversion webhook calls.
cert-manager 1.21 adds a periodic ticker that polls wall-clock time against the
renewal deadline, detecting missed renewals regardless of whether
CLOCK_MONOTONIC advanced. The webhook now recovers within one minute of system
resume.
More details are available in the PR: https://github.com/cert-manager/cert-manager/pull/8464.
ACME Renewal Information (ARI) support
cert-manager 1.21 adds experimental support for RFC 9773 ACME Renewal
Information (ARI), behind the ACMEUseARI feature gate. When enabled, and when
the ACME server advertises a renewalInfo endpoint, cert-manager queries the
server for its recommended renewal window before deciding whether to re-issue a
certificate. This allows ACME servers — including Let's Encrypt — to proactively
prompt renewal of certificates affected by mass revocations or CA key rollovers,
without requiring operators to intervene.
(cert-manager/cert-manager#8798, @hjoshi123)
AWS IAM authentication for the Vault issuer
The Vault issuer now supports AWS IAM-based authentication in three modes:
- IRSA (IAM Roles for Service Accounts): the cert-manager controller pod assumes an AWS IAM role via Kubernetes projected service account tokens.
- EKS Pod Identity: authentication via the EKS Pod Identity agent sidecar.
- Ambient credentials: uses the EC2/ECS instance metadata service when running on AWS without an explicitly configured role.
All three modes avoid the need to store long-lived AWS credentials as Kubernetes Secrets.
(cert-manager/cert-manager#8422, @bitloi)
Modern2026 PKCS#12 encoding profile
cert-manager 1.21 adds the Modern2026 profile for PKCS#12 output, based on
the go-pkcs12 library's Modern2026 encoder. This profile uses FIPS 140-3
approved algorithms (AES-256 + SHA-256 KDFs) instead of the legacy 3DES/RC2
defaults. It is suitable for environments with FIPS or compliance requirements
that prohibit older cipher suites.
(cert-manager/cert-manager#8841, @seanorama)
Certificate renewal policies
cert-manager 1.21 adds renewalPolicies to the Certificate API, allowing
operators to fine-tune when cert-manager triggers a renewal. This complements the
existing renewBefore and renewBeforePercentage fields, providing more
expressive control over renewal scheduling.
(cert-manager/cert-manager#8258, @hjoshi123)
Gateway API improvements
Several improvements to the Gateway API integration land in 1.21:
-
HTTP01 ListenerSet parentRef fallback: the new
acme.cert-manager.io/http01-parentreffallback: "true"annotation causes cert-manager to use the parent Gateway as the solver HTTPRoute parentRef instead of the ListenerSet. This enables TLS-only ListenerSets (which cannot receive HTTP challenges) to rely on a shared Gateway HTTP listener for ACME validation. (#8749, @apkatsikas) -
cert-manager.io/ignore-tls-listenersannotation: allows Gateway TLS listeners to be excluded from certificate management, useful when some listeners are managed by a different controller. (#8727, @hjoshi123) -
Additional listener protocols: the Gateway API integration now recognizes configurable listener protocols beyond the default set, making cert-manager compatible with custom protocol extensions. (#8683, @ThatsMrTalbot)
-
enableGatewayAPIconfiguration restructure: theenableGatewayAPIandenableGatewayAPIListenerSetfields onControllerConfigurationare deprecated in favor of agatewayAPI.enabled/gatewayAPI.enableListenerSetsub-struct. The old fields continue to work. (#8732, @ThatsMrTalbot)
cainjector improvements
-
CAInjectorMergingpromoted to GA: theCAInjectorMergingfeature gate is now unconditionally enabled and will be removed in a future release. This changes how cainjector merges CA data into webhook and API service objects. (#8583) -
Server-side apply unconditional: cainjector now always uses server-side apply (SSA) to patch CA bundles, and the
ServerSideApplyfeature gate is deprecated. SSA removes the last-applied-configuration annotation bloat and makes conflict detection more reliable. (#8692, @erikgb) -
--ignore-namespacesflag: the new cainjector flag accepts a comma-separated list of namespace names that cainjector will skip when watching Secrets for injection. This reduces the number of watch events in clusters with a large number of namespaces or where some namespaces contain large secrets that cainjector does not need. (#8614, @figaw)
Venafi integration updates
cert-manager 1.21 adds two improvements to the Venafi/CyberArk integration:
-
OAuth token observability: a new
AuthFailedreason on the IssuerReadycondition distinguishes authentication failures (bad or expired credentials) from transient infrastructure errors, making it easier to diagnose Venafi connectivity problems. (#8808, @FelixPhipps) -
PANW NGTS support: the Venafi issuer now supports PANW Next-Generation Trust Services as a backend, in addition to Venafi TPP and Venafi Control Plane. (#8779, @FelixPhipps)
ACME security hardening
The ACME Challenge and Order controllers now enforce stricter resource ownership rules (GHSA-8rvj-mm4h-c258):
- Challenges without a valid Order owner reference are rejected.
- Order specs are now immutable after creation.
- Pre-placed Challenges with a mismatched spec are detected and refused.
This prevents a malicious actor with write access to Order or Challenge resources from influencing ACME validation in unexpected ways.
Additionally, ACME challenges no longer permanently fail on transient network errors (TLS handshake timeouts, DNS resolution failures, context cancellation) during nonce fetches or authorization waits. The workqueue retries with exponential backoff instead.
(cert-manager/cert-manager#8948, #8760)
Notable bug fixes
-
Integer overflow in
renewBeforePercentage: Certificates with durations longer than approximately 3 years were incorrectly rejected by validation or assigned incorrect renewal times due to a 32-bit integer overflow in the percentage arithmetic. Fixed in #8947 (@ThatsMrTalbot). -
Infinite re-issuance loop: cert-manager no longer enters an infinite re-issuance loop when an issuer returns an already-expired certificate. Fixed in #8610 (@onurmicoogullari).
-
DNS issuer secrets validated before ready: the DNS issuer now validates that the referenced Secret exists and is well-formed before marking the issuer Ready, preventing silent misconfiguration. Fixed in #8255 (@Peac36).
-
Vault path traversal validation: the Vault issuer webhook now rejects
..path segments inspec.vault.pathand auth mount path fields, preventingpath.Joinfrom silently resolving relative segments before constructing the Vault API URL. Fixed in #8930. -
DNS-over-HTTPS response body unbounded read: the DNS-over-HTTPS client now caps response body reads at 128 KB, preventing a potential OOM from a malicious or misconfigured DoH resolver. Fixed in #8803 (@SebTardif).
Community
As always, we'd like to thank all of the community members who helped in this release cycle, including all below who merged a PR and anyone that helped by commenting on issues, testing, or getting involved in cert-manager meetings. We're lucky to have you involved.
A special thanks to:
@Copilot@FelixPhipps@Peac36@SebTardif@apkatsikas@bitloi@dap0am@figaw@immanuwell@jabbrwcky@jnohlgard@jsoref@ltwongaa@lunarwhite@mateenali66@onurmicoogullari@putongyong@seanorama@texasich
for their contributions, comments and support!
Also, thanks to the cert-manager maintainer team for their help in this release:
And finally, thanks to the cert-manager steering committee for their feedback in this release cycle:
v1.21.0
Changes since v1.20.0:
Feature
- Add Venafi OAuth token request observability and a new
AuthFailedIssuer condition reason to distinguish bad credentials from transient infrastructure errors. (#8808,@FelixPhipps) - Add
certificateRequestMaximumBackoffDurationcontroller configuration option to cap retry backoff time for failed CertificateRequests. Configurable via config file,--certificate-request-maximum-backoff-durationCLI flag, or Helm valueconfig.certificateRequestMaximumBackoffDuration. Defaults to 32 hours for backward compatibility. (#8893,@lunarwhite) - Add an optional
waitInsteadOfSelfCheckfield to ACME HTTP01 and DNS01 solvers so cert-manager can skip its own self-check and ask the ACME server to validate after a configured wait. (#8858,@wallrj) - Add configurable
runtimeClassNamesupport for cert-manager components and ACME HTTP01 solver pods. (#8791,@jsoref) - Add new controller flag
--acme-http01-solver-extra-labels, allowing Helm'sglobal.commonLabelsto propagate to all dynamically-created ACME HTTP01 solver resources (Pods, Services, Ingresses, or Gateway API HTTPRoutes). (#8761,@lunarwhite) - Add opt-in
startupapicheck.ttlSecondsAfterFinishedHelm value to enable automatic cleanup of the startupapicheck Job via the Kubernetes TTL-after-finished controller. (#8523,@dap0am) - Added ARI support through the ACMEUseARI feature gate. (
#8798,@hjoshi123) - Added AWS IAM authentication support for Vault issuer, including IRSA (IAM Roles for Service Accounts) and ambient credentials (EC2/ECS). (
#8422,@bitloi) - Added
cert-manager.io/ignore-tls-listenersannotation for ignoring gwapi listeners. (#8727,@hjoshi123) - Added option to specify additional listener protocols the GatewayAPI integration will consider when creating certificates. (
#8683,@ThatsMrTalbot) - Adds support for the Modern2026 go-pkcs12 profile and FIPS 140-3 (
#8841,@seanorama) - Cainjector:
- Disabled client side rate-limiting if AP&F is enabled. (
#8757,@hjoshi123) - Extend the Venafi/CyberArk integration to also support PANW NGTS. (
#8779,@FelixPhipps) - Feat(certificate): adding certificate renewal policies (
#8258,@hjoshi123) - Make cainjector use SSA unconditionally and deprecate the ServerSideApply feature gate (
#8692,@erikgb) - Processed annotations
cert-manager.io/alt-names,cert-manager.io/ip-sansto Certificates generated from ingress like objects in cert-shim controllers. (#8927,@jabbrwcky) - Promote the CAInjectorMerging feature gate to GA (
#8583,@Copilot) - When using ACME HTTP-01 with a ListenerSet, setting the annotation
acme.cert-manager.io/http01-parentreffallback: "true"causes cert-manager to use the parent Gateway as the solver HTTPRoute parentRef instead of the ListenerSet. This enables TLS-only ListenerSets to rely on a shared Gateway HTTP listener for ACME challenges. (#8749,@apkatsikas)
Bug or Regression
- BREAKING: The Helm chart no longer ships a default
RoleandRoleBindinggranting the cert-manager controller ServiceAccount permission to create tokens for itself (serviceaccounts/token: create). This RBAC was added in v1.16 (#7213) but no documented workflow requires it, and the motivating Route53 docs section was removed in Oct 2024. If you rely onserviceAccountRef.namepointing at the controller ServiceAccount (an undocumented pattern), you must now create your ownRoleandRoleBindinggrantingserviceaccounts/token: createon that ServiceAccount, or migrate to one of the documented patterns (IRSA ambient, or a dedicated ServiceAccount with its own RBAC). (#8931,@wallrj-cyberark) - ACME challenges no longer terminally fail on transient network errors (TLS handshake timeouts, DNS failures, context cancellation) during nonce fetches and authorization waits. The challenge controller returns the error and lets the workqueue retry with backoff. (
#8760,@texasich) - Add dns issuer secrets validation before marking it as ready (
#8255,@Peac36) - Add missing issuer finalizer RBAC to the order controller to support owner references (
#8654,@erikgb) - ClusterIssuer metrics collector now correctly respects the enabled-controllers configuration, avoiding a redundant startup when only operating within a namespace. (
#8822,@lunarwhite) - Fix Venafi TPP issuer setup and signing regression on master: restore authentication of the vcert connector in the client constructor, which was removed in #8808. (
#8843,@wallrj-cyberark) - Fix a performance issue in the certificateRequestApproval webhook where CertificateRequests referencing a GroupKind whose CRD is not yet installed would trigger repeated API server discovery queries on every admission request. Negative results are now cached for 30 seconds. (
#8651,@mateenali66) - Fix webhook serving certificate not being renewed after system suspend. (
#8464,@Peac36) - Fixed a rare panic in the trigger controller when a Certificate is deleted from the informer cache while a reconcile is in progress (e.g. during namespace teardown). (
#8962,@hjoshi123) - Fixed an integer overflow in
renewBeforePercentagecalculations that caused Certificates with durations longer than approximately 3 years to be incorrectly rejected by validation or assigned incorrect renewal times. (#8947,@ThatsMrTalbot) - Fixed duplicate
parentRefbug when both issuer config and annotations are present. (#8619,@hjoshi123) - Fixed infinite re-issuance loop when issuer returns an already expired certificate (
#8610,@onurmicoogullari) - Fixed local
e2e-setup-samplewebhookinstallation to use the samplewebhook image repository and tag from the saved image tarball manifest. (#8821,@wallrj) - Fixed potential OOM in DNS-over-HTTPS client by bounding response body read with io.LimitReader (128 KB cap). (
#8803,@SebTardif) - Fixed validation of timezone-prefixed renewal window cron specs without a schedule. (
#8813,@immanuwell) - Harden ACME Challenge and Order resources: reject user-created Challenges
without Order ownership, enforce Order spec immutability, and detect
pre-placed same-name Challenges with mismatched specs. (
#8948,@wallrj-cyberark) - Helm chart bugfix: rename image helper to avoid umbrella chart conflicts (
#8753,@FelixPhipps) - Helm: Fix invalid YAML generated when both
webhook.configandwebhook.volumesare defined. (#8664,@jnohlgard) - Remove ACME Challenge
createand Ordercreate/patch/updatefrom the cert-manager-edit aggregate ClusterRole to prevent direct manipulation of these internal resources (GHSA-8rvj-mm4h-c258). (#8958,@wallrj-cyberark) - Remove issuer owner reference from challenges blocking challenge garbage collection (
#8743,@erikgb) - Update logic to identify and preserve the secret matching nextPrivateKeySecretName (
#8577,@putongyong) - Vault Issuer webhook validation now rejects
..path segments inspec.vault.pathand auth mount path fields, preventingpath.Joinfrom silently resolving relative segments before constructing the Vault API request. (#8930,@wallrj-cyberark)
Other (Cleanup or Flake)
- API cleanup: removed deprecated ObjectReference (
#8625,@inteon) - Remove Helm values
prometheus.servicemonitor.targetPort,prometheus.servicemonitor.path, andprometheus.podmonitor.path. The metrics path is always/metricsand the target port is alwayshttp-metrics. Rename the controller service metrics port fromtcp-prometheus-servicemonitortohttp-metricsfor consistency with other workloads. Users must remove these keys from their value overrides before upgrading. (#8952,@erikgb) - The
enableGatewayAPIandenableGatewayAPIListenerSetfields onControllerConfigurationare deprecated and moved into thegatewayAPIsub-struct asgatewayAPI.enabledandgatewayAPI.enableListenerSet. The old fields continue to work. (#8732,@ThatsMrTalbot) - Update base images to Debian 13 (
#8849,@ltwongaa)