1.5.50
Released 16 Sep 2026
New
-
Cloudflare-proxied DNS records are now discovered on both sides of the proxy. A Cloud DNS Provider source used to scan only the address in a proxied (orange-cloud) record — the origin — so the certificate visitors actually see, on Cloudflare's edge, never reached the inventory and a certificate CertAutoPilot had uploaded to Cloudflare was never recognised as managed. Each proxied name now yields Edge and Origin rows tagged on the endpoint tables (a proxied CNAME or AAAA, previously skipped, is scanned at the edge), and a new Proxied records option on the source chooses which side is scanned.
-
Cloudflare zones and certificates can now be picked from the account. The zone list shows every zone the API token reaches and says when a zone's plan cannot hold a custom certificate at all, so that no longer surfaces first as a failed deployment.
-
AWS ACM certificates can now be picked from the region. Rows are labelled by the domain they cover and flag the ones ACM issued itself, which can never be replaced by an import.
-
PAN-OS virtual systems and certificate objects can now be picked from the firewall. On a firewall with a single virtual system the list says so, which is the case where the field should be left empty.
-
Exchange servers can now be picked from the organization. A target set to Explicit list lists the organization's servers instead of asking you to type names, and each row shows the server's role and whether its services can be restarted from CertAutoPilot.
-
A certificate whose issuance failed now says so. A first issuance that fails stays pending, because nothing was issued and the next step is to try again. The list and the detail page now show an Issuance failed tag when the last attempt failed and nothing is retrying it, so it no longer looks the same as a certificate created a moment ago.
Improved
-
Multi-server Exchange deployments now choose their own order. The server CertAutoPilot connects to is always deployed last, because restarting its web services would otherwise cut off the servers still waiting to be deployed. The rest follow a stable alphabetical order, so two runs can be compared.
-
An Exchange target that would miss part of the organization says so. The plan preview compares the servers the organization reports against the ones the target would actually reach, and names what would be left behind — the case that otherwise goes unnoticed until a certificate expires on a server added after the target was set up. The plan also lists only the servers the run will touch, rather than the whole organization.
-
Microsoft Exchange is no longer marked experimental.
-
The Exchange plan preview now names the certificate that OWA, ECP and EWS are currently using. Exchange itself will not report which certificate serves which service, so the preview reads the web binding on the server instead. The remaining services are still listed as unknown rather than guessed.
-
Certificates in a deployment preview are identified by subject, not only by thumbprint. A forty-character hash says nothing about which certificate is about to be replaced; the plan and the preview now show, for example,
CN=mail.example.combeside it. -
A preview separates what it could not determine from what it found wrong. A remote system that declines to report something is now shown as a note rather than a warning, so the warning list stays worth reading.
-
A distribution waiting for its schedule window is no longer scored as a stall. The certificate detail shows Scheduled with the time the window opens instead of Pending since…, and the risk assessment lists the wait as an informational signal rather than a risk.
-
The deployment preview now says what would actually change. AWS ACM refuses up front an ARN that ACM issued itself and cannot be imported over, and names what the re-import would replace; Kubernetes lists the Secrets that are already current instead of leaving them out; Huawei Cloud says whether it would create or update the certificate object rather than "create or update"; Cloudflare warns when the zone's plan cannot hold a custom certificate and names the hosts being replaced; NetScaler says how many virtual servers keep their bindings; and on cPanel each domain shows the certificate it has today.
-
An Exchange service with no Windows service behind it is now reported. Asking to restart UM, UM Call Router or Federation used to do nothing at all, silently; the run now warns and names the service.
Changed behaviour
Each proxied Cloudflare name is now also probed at the Cloudflare edge, so new endpoint rows and newly discovered edge certificates appear on the next scan — with the usual new-certificate notifications, and an SNI required finding for each edge address, since the edge refuses handshakes without a server name. The run's target count, which the source's Max Targets limit applies to, grows by the edge addresses; a source already near its limit becomes partial and stops detecting disappeared endpoints until the limit is raised. Set Proxied records to Origin only on a source to keep its previous behaviour.
- Zone names from a DNS zone transfer or a cloud DNS provider are no longer subject to the deep-SNI candidate budget. A frontend that serves many names from one address (a Cloudflare edge above all) used to have its names beyond the budget silently dropped and its disappearance detection skipped; every listed name is now probed, and the budget applies only to names found by crawling certificates.
Exchange only serves RSA certificates, and CertAutoPilot issues ECDSA by default. An ECDSA certificate used to import successfully and then stay invisible to Exchange; such a deployment is now refused up front, and the plan preview warns before you run anything. Re-issue the certificate with an RSA key (2048 bits or more) for any Exchange target.
If you restart services across an organization (all_org or a server list),
CertAutoPilot now connects to each Exchange server itself instead of reaching
across from the one it is pointed at. Open WinRM to every server in the list and
address each by its full domain name (a short name is resolved through the
organization); an IP address has its restart skipped with a warning.
-
Certificates and passwords no longer travel on the remote command line. Windows deployments (IIS, Exchange and the generic WinRM module) now send the file on the command's standard input, and the server checks that what arrived matches what was sent.
-
Two transfer metrics are gone.
certautopilot_winrm_transfer_fallback_totalandcertautopilot_iis_pfx_fallback_totalcounted a fallback the new transfer does not have. Remove them from any dashboard that charts them. -
Windows file paths longer than 252 characters are now refused. The destination has to leave room for the temporary name the transfer writes beside it, so an over-long path fails validation instead of failing on the server.
-
Every Exchange operation writes a temporary file to the target. The service account's password now travels as an access-restricted file that is deleted afterwards, rather than inside the command. This includes the health check, so it is no longer a read-only probe.
A review of every distribution module against its documentation tightened
several rules that used to fail only at deploy time, or never. Existing targets
keep working until they are edited; the next save of one may now be refused:
an SMTP target using PLAIN/LOGIN must reference an smtp_password
credential of its own project (and a PKCS#12 passphrase credential for
pkcs12 payloads), and its from_address must be a bare mailbox; an F5
key_name is only accepted together with an explicit cert_name; an
Exchange host must be the server's Active Directory FQDN; a MerlinCDN
API host must be https://api.merlincdn.com or a loopback/private address —
a deploy to any other host is now refused; a webhook method must be POST,
PUT or PATCH; a PAN-OS target with auto_commit off cannot carry
TLS-fingerprint validation endpoints; a NetScaler http_timeout must be
5–300 s; SSH/Windows path sets and action sets are validated for owner,
mode, run_as, shell and timeout. On the appliance side, a NetScaler NITRO
user now needs show ns version for deploys and rollbacks (the deploy starts
with the health check's probe), and a Vault token must be allowed to read
the target's secret path or the health check reports the target unhealthy.
-
AWS ACM: adopted certificates are tagged after their first re-import. A certificate adopted by ARN now receives the
certautopilot:certificate-idtag (and the Name tag when configured and absent) so it can be rediscovered if the pin is cleared. This usesacm:AddTagsToCertificate; a policy without it logs a warning and the deployment still succeeds. A pinned ARN from another region is rejected before any AWS call. -
Azure Key Vault: the first import of a name sets the key policy to exportable with no key reuse, so consumers such as Application Gateway that need an exportable private key work without a manual policy change; existing names and later policy edits are untouched.
-
Cloudflare: a target with an empty Type now creates a modern
sni_customcertificate, as the form always promised; previously Cloudflare created alegacy_customcertificate in the zone's legacy slot. An existing legacy certificate is not converted. An empty Bundle Method is sent explicitly asubiquitous, Cloudflare's own default. -
cPanel/WHM: the
whm_userfield is deprecated. WHM has no account parameter for certificate installs and always resolves the owner from the domain, so the value is no longer sent; the deploy log now shows the account WHM chose per domain, and an override settingwhm_useron acpanel-mode target is refused. cPanel/WHM hosts now go through the same outbound network policy as the other API modules (link-local, cloud-metadata and DNS-rebinding answers refused); private and loopback hosts remain reachable. -
Exchange: the server picker stores each picked server by its full domain name (the short name remains the label); existing short-name entries keep working.
EXCHANGE_EMS_UNAVAILABLEis now retried automatically, because it also covers a leaked session exhausting the per-user limit and the endpoint being down while IIS restarts; a permanent cause fails again on the retry. -
F5 BIG-IP: when an override or auto-naming changes the effective cert name, the key object name follows it; previously every certificate on a shared target could overwrite one explicit key object. A rejected login and any 401/403 during a run are now
F5BIGIP_AUTH(not retried) instead of a retriedF5BIGIP_CONNECT; an in-place update of an object F5 does not have isF5BIGIP_NOT_FOUND. The device lock and fan-out grouping use the port actually dialed (443 with HTTPS, 80 with HTTP, or the explicit port). -
Huawei Cloud: the Default (all targets) override row accepts only
certificate_name; acertificate_id,domain_idordomain_namethere is refused, and rows saved earlier are reduced to their name at deploy time instead of pointing every target at one object. A 400 answer is nowHUAWEICLOUD_VALIDATIONand not retried; the ELB name lookup follows the API's paging (up to 500) and fails withHUAWEICLOUD_CONFLICTwhen cut off without an exact match, instead of creating a possible duplicate. -
IIS: file uploads honor the command timeout. The PFX, its password file and staged scripts are each bounded by the target's command timeout, so a host that stalls mid-transfer no longer holds the target for the whole per-host budget. Raise the command timeout for very slow WinRM links.
-
Kubernetes: a target whose API client cannot be built (missing or unparseable kubeconfig, unknown context,
in_clusteroutside a pod, invalidproxy_url) now fails with the newK8S_VALIDATIONcode and is not retried;K8S_CONNECTis reserved for an unreachable API server. A 401 during a Secret read/write or restart isK8S_FORBIDDEN(not retried), like a 403. -
MerlinCDN: a binding failure caused by a rate limit or a 5xx/network error is now
MERLINCDN_QUOTA/MERLINCDN_CONNECTand retried; only a rejected binding remainsMERLINCDN_BIND. -
NetScaler: a deploy whose certkey already holds the certificate no longer rewrites it — the run logs "already current", reports the target unchanged and still saves the configuration when
save_configis on. Failures in the chain link step are nowNETSCALER_LINK;NETSCALER_CHAINis reserved for installing intermediates, and the unusedNETSCALER_NOT_FOUNDcode is gone. -
SMTP: relay negotiation mismatches are no longer retried. STARTTLS required but not advertised, AUTH or the chosen mechanism not offered, and a password refused over a plaintext connection fail with
SMTP_VALIDATIONinstead ofSMTP_TRANSIENT. -
SSH: turning off Parallel execution (Settings → General) now forces one target at a time for SSH too; a non-zero SSH Max Concurrency used to override the switch. On every run the module re-checks mode and owner of unchanged files and corrects drift with a job-log warning, and the dry-run line for an action set states the trigger the deploy would use.
-
Vault: the health check reads the target's secret path (or
certautopilot/__healthcheck__without a fixed path) with the target's token — 200 or 404 is healthy, 403 is unhealthy — so an expired or under-privileged token no longer passes. A 403 on the secret read or write isVAULT_AUTH_FAILEDand not retried; a dry run marks the target unreachable when the read fails. -
Webhook: a 4xx answer other than 408, 425 or 429 ends the delivery attempts immediately instead of being retried like a 5xx, and an unparseable URL is not retried either. The
X-Idempotency-Keyheader now ends with the distribution job id (<certificate_id>-<fingerprint>:<job_id>), so a receiver that deduplicates on it no longer drops a rollback re-delivery.
Fixed
-
A Cloudflare target using an account-owned API token no longer shows as unhealthy while its deployments succeed. The health check asked Cloudflare to verify the token through a route that only answers for user-owned tokens, so an account-owned token (the kind the dashboard now creates by default) was reported as invalid even though every upload worked. The check now reads the target's zone with the token, which proves both that the token is valid and that it reaches the zone, and it reports the zone's plan. The connection test of a Cloudflare discovery DNS provider had the same blind spot and now lists a zone instead.
-
An existing Cloudflare custom certificate can now actually be adopted. The Certificate ID field on a Cloudflare target and in a distribution override only accepted a 32-character hexadecimal id, but Cloudflare identifies custom certificates by a UUID (
373ec38f-51ac-…), so every real id the dashboard and the certificate picker show was refused. Both spellings are accepted now. -
Cloudflare renewals after adopting a pinned certificate, and recovery after a certificate was removed in the Cloudflare dashboard, no longer fail with "Invalid certificate". Cloudflare answers a certificate id that no longer exists with that message (not with "not found"), and the module read it as a permanent validation error. It is now recognised as a missing certificate, so a pin that was re-keyed by the adoption falls back to the remembered id and a deleted certificate is uploaded afresh, as documented. Cloudflare's per-minute limit on certificate updates is likewise treated as a transient condition that is retried, not as a failed deployment; a zone whose custom-certificate allocation is full is reported as a plan limit instead of a rejected token; and a malformed or rejected token is reported as an authentication failure even when Cloudflare returns it as a bad request.
-
Creating a certificate whose name is already used in the project now says so. The request was rejected with the database's raw duplicate-key text; it now answers with a plain "a certificate named … already exists in this project".
-
Removing the superseded certificate no longer fails when services are restarted. On Exchange the removal was issued after the restart, but the restart drops the very management session the removal needs — so Delete old certificate quietly never worked while Restart services was on. The removal now happens first.
-
Redeploying a certificate to an Exchange server that another certificate has since taken over no longer reports "already current" and does nothing. Exchange gives a service to exactly one certificate, so deploying a second certificate to the same target takes the bindings from the first — while the first one's record still said it held them. With more than one certificate on an Exchange target, every run now re-imports and re-enables instead of skipping, and a warning explains that the two are displacing each other.
-
An Exchange service that the server refused is no longer reported as deployed. Exchange turns down a certificate for POP or IMAP when its subject is a wildcard — as a warning, while still reporting success — so the run came back green with the service still on the old certificate. Exchange's warnings now travel with the result, and the summary says plainly that a requested service may not be bound.
-
A wildcard certificate aimed at POP or IMAP is flagged before deployment. The plan preview and the run itself now name the affected services and the command that fixes each one, instead of leaving it to be discovered on the server afterwards. IIS and SMTP are unaffected and still deploy normally.
-
Testing an RFC 2136 credential in GSS-TSIG mode now checks the Kerberos configuration it depends on. The test passed on a host with no
krb5.conf, and the problem only appeared when a certificate failed to issue. It now reports a missing, unreadable or realm-less configuration immediately, names the file, and points at the Windows DNS (WinRM) provider for operators who would rather not set one up. Nonsecure and TSIG credentials are unaffected. -
An Azure Key Vault target no longer reports itself healthy when nothing can be deployed to it. The check only listed certificates, and a vault keeps serving that list even when it refuses every read of an individual certificate — the first thing a deployment does. The check now performs that read too, so the target turns red at the moment deployments would start failing rather than at the next renewal.
-
Azure Key Vault failures caused by a disabled subscription now say so. Any refusal from the vault was reported as a missing permission, sending operators to grant a role that was never missing. A refusal caused by a disabled or suspended Azure subscription now names it, and says that no permission change will help.
-
Exchange deployments no longer fail with "the command line is too long". The instructions sent to an Exchange server had outgrown the limit Windows puts on a command, so every deployment failed before it began.
-
Exchange failures now say why the management session refused to open. The server's own explanation used to be discarded, leaving only "Management Shell unavailable"; it now reaches the deployment error, the plan preview and the health check.
-
A failed Exchange session partway through a multi-server deployment no longer hides what already worked. The run reported total failure although the certificate was live on the servers already reached, and recorded nothing — so the next run lost the previous certificate it needs to clean up. It now reports a partial result naming the servers that succeeded, the ones that failed, and the ones it never reached.
-
A failed Exchange service restart is no longer silent. Restarting a service on another server could not authenticate and reported nothing, so the deployment looked successful with nothing restarted. A failure now names the server, the service and the reason, and the next run re-attempts it.
-
An Exchange target serving several certificates can no longer delete the wrong one. On a target whose deployment record predates per-certificate history, a second certificate could inherit the first one's record and — with Delete old certificate on — remove the first certificate from the server. Each certificate now only ever removes its own previous version; the first deployment after upgrading leaves the superseded certificate in place.
-
A certificate rejected by the CA over DNS now records which nameservers were missing the record. The check runs against the zone's authoritative nameservers at the moment of the failure and writes the answer to the job log, so a repeat problem is diagnosable instead of looking like bad luck.
-
The Exchange plan preview no longer implies a certificate is unbound when it cannot tell. An Exchange server does not report per-certificate service bindings over its management endpoint, so the preview now says the information is unavailable instead of showing nothing.
-
Windowed distribution schedules no longer pile up "scheduled" jobs. A distribution waiting for its window gained one more pending job on every sweep, so a single upcoming window could show a dozen. One wake is now kept per distribution, a wake for a window you have since moved is cancelled, and jobs an earlier version left behind are retired.
-
A Microsoft CA approval wait can no longer fork into two polling chains. A worker restart at the wrong moment could re-run the interrupted poll and start a second, independent chain against the CA. The next poll is now armed exactly once.
-
Fan-out batches that wait on a busy device retry exactly once. A worker restart during the wait could queue the same retry twice, over-counting the distribution's totals and leaving it looking stuck.
-
Revoking a certificate twice in quick succession no longer queues two revocation jobs. The second request returns the job already queued.
-
Switching a distribution off now also stops work already queued for it. A deployment scheduled days earlier could still run after the distribution was disabled; disabling it, changing its schedule or unlinking it now clears the queued work. Running a disabled distribution by hand still works, which is how you test one.
-
A discovery source is scanned by one job at a time. Triggering a scan while the previous scan of that source is still running returns the running job instead of starting a second one.
-
AWS ACM: ECDSA and RSA 3072/4096 certificates are now found. Tag discovery and the picker ask ACM for every key type; AWS's default listing returns only RSA 1024/2048, so an ECDSA certificate was invisible and a duplicate was imported on every run once the remembered ARN was lost. A deleted pinned ARN now falls back to the remembered ARN, then tag discovery, then create, instead of importing a duplicate each run; adopting a certificate ACM issued itself fails clearly before the import; the
certificate_namelimit is 255 characters, matching AWS. -
Azure Key Vault: a vault host that does not resolve in DNS is reported as
AZUREKV_NOT_FOUNDand not retried, instead of burning the retry wave asAZUREKV_CONNECT; a soft-deleted name is recognised by Azure's error code as well as by the message text. -
Cloudflare: a redirect from the API is reported as
CLOUDFLARE_CONNECTand retried, not as a validation failure; an upload Cloudflare rejects with its error 1002 isCLOUDFLARE_VALIDATIONrather than a missing certificate id; a token pasted with whitespace is trimmed and a blank token refused at save. -
cPanel/WHM: whm-mode installs send the CA chain in the field WHM actually reads, so the served chain is the one CertAutoPilot deployed, and the install outcome WHM reports in the response body is checked, so a refused install is a failed domain with WHM's reason instead of a success.
-
Exchange: a server listed by its short name is now restarted when service restarts are on (the run asks the organization for its FQDN first); a single-server target no longer warns "server … is no longer in this target" on every renewal; the plan preview names the certificate on the
:443binding rather than whichever HTTPS binding came first. -
F5 BIG-IP: uploaded PEM files are removed from
/var/config/rest/downloadson every failure path, and a removal that fails is logged naming the file; a network error during the import-only lookup isF5BIGIP_CONNECT; when the token-timeout extension is refused the module assumes the BIG-IP default of 1200 s and re-authenticates in time instead of continuing with an expired token. -
Huawei Cloud: an ELB or WAF deploy no longer creates a second certificate object when reading the remembered one fails transiently; only a definitive 404 falls back to the name lookup. A WAF create answer without an id now carries
HUAWEICLOUD_CONNECT. -
IIS: multi-binding sweeps are idempotent again. In
all_matching,explicit_listandall_sitesmodes the module misread the certificate on each binding, so every run re-bound everything, Dry Run never saidalready-current, and Remove old cert after bind never found the previous certificate. An unchanged certificate now updates nothing, the pickers show the certificate actually on each binding (SNI bindings included), and the previous certificate is removed after a renewal when nothing else references it. Bind errors insinglemode carryIIS_BINDING_FAILED; a filesystem access-denied on the staged file isIIS_IMPORT_FAILEDrather thanIIS_AUTH; a failed post-bind validation reports the binding as changed so automatic rollback can act; Dry Run mirrors the deploy inexplicit_listandsinglemodes; an unsupported picker kind is a request error, not a host failure. -
Kubernetes: the target form no longer requires a credential in In Cluster mode, and the pickers no longer send one for an
in_clustertarget. -
MerlinCDN: old certificates displaced by bindings healed on a later run are now deleted (with
delete_old_certon) instead of staying in the workspace; an upload id missing from the response is recovered from the certificate's name, and the run warns when a stray upload may remain. -
NetScaler: an unreachable appliance is
NETSCALER_CONNECTand a 401/403 at any step isNETSCALER_AUTH, instead ofNETSCALER_UPLOAD/UPDATE; two targets naming the same appliance in one run execute one after another; the dry run's link actions start from the certkey the deploy will actually link and show "skip" when it is already current. -
PAN-OS: the dry run no longer plans a new import when the material already sits uncommitted in the candidate configuration with
auto_commitoff; the in-run serialization, fan-out grouping and device lock all identify a firewall by host and port, so a firewall's targets are never split across batches that queue on each other's lock. -
SMTP: a PKCS#12 passphrase credential from another project could be referenced by a target; it is now scoped to the target's project and type at save and refused again at deploy. A
from_addresswith a display name no longer breaks the EHLO greeting (it is rejected up front), and the form no longer offers a passphrase credential in the password picker. -
SSH: a host refusing a file write (permission denied, missing directory, read-only filesystem) is reported as the new non-retried
SSH_PERMISSIONcode instead ofFILE_UPLOAD; a handshake that fails for a transport reason isSSH_CONNECT(retried) rather thanSSH_AUTH; a path set or action set from another project is skipped with a warning, matching WinRM; targets that fail before connecting carrySSH_VALIDATIONinstead of no code. -
Vault: connections are released per target instead of staying open until the server times them out, and the target form's path preview lists all four managed metadata keys.
-
Webhook: a payload template that fails to render is
WEBHOOK_TEMPLATE(not retried) instead of a retryableWEBHOOK_CONNECT; the error code reflects the last attempt; the attempt count shows the requests actually made; the Retry Count help, payload example and template reference describe what is really sent. -
Windows (WinRM): the command allow-list no longer opens up silently. A pattern that could not be used at deploy time used to be skipped, and when every pattern was skipped all commands were allowed; the target now fails with
WINRM_VALIDATIONand runs nothing, and patterns over 512 characters are refused at save. Configuration errors are recorded asWINRM_VALIDATIONrather thanWINRM_EXEC, file-write failures asWINRM_FILE, and a PowerShell syntax error asWINRM_PS_SYNTAX. A Windows PathSet path such asa..pemis accepted (only a..segment is refused), and the ActionSet timeout hint no longer suggests a 300-second default.