Module health checks
What the per-module health check verifies (connectivity + authentication, per target), how to run it from the UI or API, and what a green result does not guarantee.
What a health check is
Every distribution module implements HealthCheck: a cheap probe run against all targets resolved from a module configuration. It answers one question per target — can CertAutoPilot reach this target and authenticate? — without touching any certificate material.
It is read-only on every module but Exchange. An Exchange check has to open an Exchange management session, which means uploading the service account's password to a temporary file on the server and deleting it afterwards, so the probe writes to the target's temporary directory. See Exchange.
Modules that implement the detailed variant return a per-target result list (name, address, healthy, error); others return a single pass/fail with the first error.
What each module checks
| Module | Probe | What passes |
|---|---|---|
| SSH | open SSH connection with the target's credential | TCP connect + SSH auth succeed |
| Kubernetes | GET /version on the API server | API server reachable and the client builds. It exercises no RBAC, so a missing Secret, restart or cleanup permission passes here and fails at deploy time instead. |
| IIS | WinRM connect + run a trivial PowerShell probe | WinRM reachable, auth OK, remote PowerShell executes (exit 0, expected output) |
| WinRM (generic) | exec Write-Output "OK" over WinRM | transport reachable, auth OK, PowerShell executes |
| Webhook | HTTP HEAD to the base URL (5 s timeout) | endpoint answered at all — the status code is not evaluated |
| NetScaler | NITRO API ping (5 s timeout) | NSIP reachable, credential accepted |
| F5 BIG-IP | iControl REST version query (5 s timeout) | management endpoint reachable, credential accepted |
| Vault | authenticate with the target's credential | Vault reachable, login succeeds (detailed variant also reports mount reachability) |
| Huawei Cloud | ELB: ListCertificates with a dummy name filter; CDN: client init + domain_id presence check; WAF: client init against the region endpoint | region endpoint reachable, AK/SK accepted |
| SMTP | dial the relay, STARTTLS/SMTPS as configured, EHLO + QUIT — no AUTH attempted | relay reachable and speaks SMTP (deliberately does not test credentials, to avoid filling the relay's audit log with failed probes) |
| AWS ACM | acm:ListCertificates in the target region (5 s timeout) | region endpoint reachable, access key valid, list permission granted |
| Cloudflare | Zone read (GET /zones/{id}, resolving zone_name first) | Cloudflare API reachable, API token valid and scoped to the zone; the zone's plan is reported, and a plan that cannot hold a custom certificate is named |
| Azure Key Vault | AAD token acquisition + single-page certificate list (GET /certificates?maxresults=1) + one per-object read (GET /certificates/{name}, where 404 is the healthy answer) | AAD credential valid, vault reachable, List and Get permissions granted, owning subscription active — a vault serves the list even when it refuses every per-object read |
| cPanel / WHM | Authenticated probe (cPanel installed-hosts list / WHM version) | Host reachable on the API port, username + API token valid |
| MerlinCDN | authenticated GET on the target's distribution | API reachable, PAT + org/workspace headers accepted, distribution exists |
| Exchange | WinRM connect + load EMS + Get-ExchangeServer/Get-ExchangeCertificate | WinRM reachable, credential accepted, Exchange Management Shell available, certificate list readable (reported as its own check line) |
| PAN-OS | authenticate against the XML API + read system info (reports the PAN-OS version) | management interface reachable, credential accepted; fails when the target sets a vsys but multi-vsys is disabled |
Running a health check
From the UI: Settings → Distribution → Modules → Health Check button on the module configuration row. A modal shows the per-target outcome (address, healthy/unhealthy, error message).
From the API (project Admin role required):
POST /api/v1/projects/{project}/modules/{id}/health
Response:
{
"healthy": false,
"targets": [
{ "name": "nginx-prod-01", "address": "10.0.4.11:22", "healthy": true },
{ "name": "nginx-prod-02", "address": "10.0.4.12:22", "healthy": false,
"error": "SSH connect to 10.0.4.12:22: dial tcp: i/o timeout" }
]
}
What it does NOT verify
A green health check means reachable + authenticated — nothing more. It does not verify:
- Write permissions — the SSH user may connect fine but lack write access to the PathSet directories; the Kubernetes token may list namespaces but be forbidden from updating Secrets; the AWS key may list certificates but be denied
acm:ImportCertificate. - Paths and resources — PathSet directories, IIS site names, Vault mount paths (simple check), NetScaler certkey names, Webhook response semantics (any HTTP answer passes, even a 500).
- Post-deploy actions — ActionSet commands, sudo rules, service reload permissions.
- SMTP authentication — by design (see table above).
Use DryRun on the distribution for a deeper pre-flight: it connects with the real config and reports exactly what Execute would do per target.
The check runs on demand only — it is not scheduled. A target that was green last week can still fail tonight's renewal distribution. Treat it as a bring-up and troubleshooting tool, not as monitoring.
Interpreting failures
| Symptom | Likely cause |
|---|---|
| Connect / dial timeout | Firewall between backend and target, wrong host/port, target down. Test from the backend host, not your laptop. |
| Auth error | Wrong or rotated credential; for WinRM/IIS also check the auth type (NTLM vs Basic) matches the server config. |
| Only some targets red | Per-host issue (host down, per-host firewall rule, host-specific credential) — the module config itself is fine. |
| All targets red | Shared cause: expired credential, egress rule, DNS. |
See also
- Targets & groups — health check
- Distribution overview
- Post-distribution validation
- Module credentials
Running a check
Two routes exist: POST /projects/{project}/modules/{id}/health probes every target of a module config, and POST /projects/{project}/targets/{id}/health probes exactly one target. Both are project admin actions and neither runs automatically when a target is saved.