Argo CD Health Status Explained: Aggregation Logic and Custom Checks
Argo CD health status aggregates individual Kubernetes resource health using a priority-based ranking system (Healthy → Suspended → Progressing → Missing → Degraded → Unknown) and supports extensible Lua scripts for custom resource definitions.
Argo CD continuously monitors the health of deployed applications by evaluating every managed resource in the cluster. According to the argoproj/argo-cd source code, the controller’s health determination logic combines built-in Go implementations for standard resources with configurable Lua overrides for custom CRDs, providing real-time visibility through both the web UI and CLI.
How Argo CD Aggregates Application Health Status
The core health aggregation logic resides in the controller’s setApplicationHealth function, located in controller/health.go. This function evaluates each resource managed by an application and determines the overall health using a five-step process:
-
Filters ignored resources – Resources annotated with
argocd.argoproj.io/ignore-healthcheck: "true"are skipped (lines 46‑49). -
Skips self-referential applications – An application that manages itself does not affect its own health status (line 58).
-
Retrieves individual health – For existing resources, the controller invokes
health.GetResourceHealthfromgitops-engine/pkg/health/health.go, applying any Lua overrides. -
Applies priority-based aggregation – The application inherits the most severe status from its constituent resources, following the priority order: Healthy → Suspended → Progressing → Missing → Degraded → Unknown.
-
Records degradation causes – When health is degraded, the controller tracks up to three responsible resources using the
maxHealthCausesShownconstant and formats them via theformatHealthCausesfunction.
Built-In Health Checks for Standard Kubernetes Resources
Argo CD ships with Go-based health implementations for common Kubernetes resource types located under gitops-engine/pkg/health/. These built-in checks evaluate specific conditions without requiring custom configuration:
-
Deployment (
health_deployment.go): Verifies thatobservedGenerationmatches the desired generation and that replica counts are up-to-date. -
Service (
health_service.go): For LoadBalancer types, checks for the presence of an external IP or hostname. -
Ingress (
health_ingress.go): Validates that a load-balancer ingress entry exists. -
CronJob (
health_cronjob.go): Evaluates the last schedule status to determine if the resource is Progressing or Degraded.
These implementations return a HealthStatus struct that the controller aggregates according to the priority rules defined in controller/health.go.
Custom Health Checks with Lua Scripts
When managing custom resource definitions (CRDs) that lack built-in checks, Argo CD allows operators to define health logic using Lua scripts. The Lua engine implementation in util/lua/lua.go loads and executes these scripts at runtime, producing a HealthStatus struct with status and optional message fields.
Defining Custom Health Scripts
Place Lua scripts in the resource_customizations/<group>/<kind>/health.lua path, or register them via the argocd-cm ConfigMap using the key resource.customizations.health.<group>_<kind>. For example, to enable standard Lua libraries for a specific check, use the resource.customizations.useOpenLibs.<group>_<kind> key.
The following example configures a custom health check for cert-manager.io/Certificate resources:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.useOpenLibs.cert-manager.io_Certificate: "true"
resource.customizations.health.cert-manager.io_Certificate: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for _, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" and condition.status == "False" then
hs.status = "Degraded"
hs.message = condition.message
return hs
end
if condition.type == "Ready" and condition.status == "True" then
hs.status = "Healthy"
hs.message = condition.message
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for certificate"
return hs
Wildcard Support for Resource Groups
You can apply health checks to entire API groups or kinds using wildcards (*). The implementation uses the doublestar glob library to match patterns such as *.aws.crossplane.io/*:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations: |
"*.aws.crossplane.io/*":
health.lua: |
hs = {}
if obj.status ~= nil and obj.status.state == "available" then
hs.status = "Healthy"
else
hs.status = "Degraded"
hs.message = obj.status.state or "unknown"
end
return hs
Monitoring Health Status in the Argo CD UI and CLI
Once calculated, health status surfaces in both the web interface and command-line tools, reflecting the aggregation logic from controller/health.go.
Web UI: The Applications view displays an aggregated health badge. Selecting a specific resource reveals its individual health status and a "Caused by …" summary generated by the formatHealthCauses function.
CLI: The argocd app get command (implemented in cmd/argocd/commands/app.go) retrieves and displays the current health status along with problematic resources:
argocd app get my-app --refresh
Example output includes:
Health: Degraded
Caused by apps/Deployment:default/nginx-deployment
Summary
- Argo CD determines application health status by aggregating individual resource health using the priority order: Healthy → Suspended → Progressing → Missing → Degraded → Unknown.
- The aggregation logic lives in
controller/health.go, specifically thesetApplicationHealthfunction, which respects ignore annotations and skips self-referential applications. - Built-in checks for standard resources (Deployments, Services, Ingresses) reside in
gitops-engine/pkg/health/and evaluate resource-specific conditions. - Custom Lua scripts extend health checking to CRDs via
argocd-cmConfigMap entries orresource_customizations/paths, with wildcard support using thedoublestarlibrary. - Degradation causes are tracked (up to three resources via
maxHealthCausesShown) and displayed in both the UI and CLI.
Frequently Asked Questions
How does Argo CD determine the overall health of an application?
Argo CD evaluates every managed resource through the setApplicationHealth function in controller/health.go. It polls each resource's health status—using built-in Go logic or custom Lua scripts—and assigns the application the most severe status found, following the priority chain from Healthy (best) to Unknown (worst).
Can I disable health checks for specific resources?
Yes. Add the annotation argocd.argoproj.io/ignore-healthcheck: "true" to any resource manifest. The controller will skip health evaluation for that resource during aggregation, as implemented in lines 46‑49 of controller/health.go.
Where are custom Lua health scripts stored in the Argo CD configuration?
Custom scripts can be placed in the resource_customizations/<group>/<kind>/health.lua file path within your Argo CD configuration, or defined inline in the argocd-cm ConfigMap using keys like resource.customizations.health.<group>_<kind>. The Lua engine in util/lua/lua.go executes these scripts at runtime.
What is the priority order for Argo CD health statuses?
Argo CD uses the following priority order when aggregating health status, from least severe to most severe: Healthy, Suspended, Progressing, Missing, Degraded, Unknown. The application status reflects the worst condition present among its managed resources.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →