# Argo CD Health Status and Monitoring: A Complete Guide to Application Health Checks

> Master Argo CD health status monitoring. Learn how Argo CD checks application health using Go and Lua scripts for Kubernetes resources and CRDs.

- Repository: [Argo Project/argo-cd](https://github.com/argoproj/argo-cd)
- Tags: how-to-guide
- Published: 2026-07-14

---

**Argo CD aggregates the health status of every managed Kubernetes resource to determine an application's overall health, using built-in Go checks for standard resources and Lua scripts for custom CRDs.**

Argo CD health status and monitoring provide real-time visibility into whether your deployed applications are running as expected. The system evaluates each managed resource through a sophisticated aggregation algorithm implemented in the controller's `setApplicationHealth` function. This article explores the technical implementation in the `argoproj/argo-cd` repository, covering built-in health checks, custom Lua scripts, and monitoring interfaces.

## How Argo CD Calculates Application Health

The core health evaluation logic resides in [`controller/health.go`](https://github.com/argoproj/argo-cd/blob/main/controller/health.go), where the `setApplicationHealth` function processes every resource belonging to an application.

### The Health Aggregation Algorithm

For each resource, the controller performs the following steps:

1. **Filters ignored resources** – Resources annotated with `argocd.argoproj.io/ignore-healthcheck: "true"` are skipped entirely (lines 46-49 in [`controller/health.go`](https://github.com/argoproj/argo-cd/blob/main/controller/health.go)).
2. **Skips self-referencing apps** – An application that manages itself does not affect its own health calculation (line 58).
3. **Obtains health records** – For existing resources, the controller calls `health.GetResourceHealth` from [`gitops-engine/pkg/health/health.go`](https://github.com/argoproj/argo-cd/blob/main/gitops-engine/pkg/health/health.go), applying any Lua overrides if configured.
4. **Aggregates the worst status** – The application health becomes the most severe status among its children.
5. **Tracks degradation causes** – Up to three resources causing degradation are recorded using the `maxHealthCausesShown` constant and formatted via the `formatHealthCauses` function.

### Health Status Priority Order

Argo CD uses a strict priority hierarchy when aggregating health statuses across resources:

**Healthy → Suspended → Progressing → Missing → Degraded → Unknown**

This means if any single resource is **Degraded**, the entire application shows as Degraded, even if all other resources are Healthy. The controller evaluates this priority in [`controller/health.go`](https://github.com/argoproj/argo-cd/blob/main/controller/health.go) during the aggregation phase.

## Built-In Health Checks for Standard Resources

Argo CD ships with Go implementations for common Kubernetes resource types located under `gitops-engine/pkg/health/`. These built-in checks verify specific conditions for each resource type:

- **Deployments** ([`health_deployment.go`](https://github.com/argoproj/argo-cd/blob/main/health_deployment.go)): Verifies the observed generation matches the desired generation and that replica counts are up-to-date.
- **Services** ([`health_service.go`](https://github.com/argoproj/argo-cd/blob/main/health_service.go)): For LoadBalancer services, confirms an external IP or hostname is present.
- **Ingresses** ([`health_ingress.go`](https://github.com/argoproj/argo-cd/blob/main/health_ingress.go)): Validates that a load-balancer ingress entry exists.
- **Jobs** ([`health_job.go`](https://github.com/argoproj/argo-cd/blob/main/health_job.go)): Checks completion status and failure conditions.
- **PersistentVolumeClaims** ([`health_pvc.go`](https://github.com/argoproj/argo-cd/blob/main/health_pvc.go)): Verifies binding status.

These implementations are automatically invoked by `GetResourceHealth` when no custom Lua override exists for the resource type.

## Custom Health Checks with Lua

When managing custom resources or CRDs without built-in support, Argo CD allows you to define health logic using Lua scripts. The Lua engine implementation lives in [`util/lua/lua.go`](https://github.com/argoproj/argo-cd/blob/main/util/lua/lua.go).

### Configuring Custom Health Scripts

Custom health checks are registered via the `argocd-cm` ConfigMap using the key `resource.customizations.health.<group>_<kind>`:

```yaml
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

```

The script must return a `HealthStatus` structure with a `status` field and optional `message` field. Place standalone scripts in `resource_customizations/<group>/<kind>/health.lua` (e.g., [`resource_customizations/cert-manager.io/Certificate/health.lua`](https://github.com/argoproj/argo-cd/blob/main/resource_customizations/cert-manager.io/Certificate/health.lua)).

### Wildcard Support for Resource Groups

You can enable health checks for entire resource groups using wildcards. The implementation uses the `doublestar` glob library to match patterns:

```yaml
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

```

Wildcard patterns are particularly useful when managing multiple CRDs from the same provider, such as AWS Crossplane resources.

## Monitoring Health in the UI and CLI

Argo CD exposes health status through both its web interface and command-line tools, leveraging the aggregation logic from [`controller/health.go`](https://github.com/argoproj/argo-cd/blob/main/controller/health.go).

### Visual Indicators in the Argo CD UI

The Application view displays an aggregated health badge that reflects the worst status among all resources. Clicking on individual resources reveals:

- The specific health status (Healthy, Progressing, Degraded, etc.)
- Any error messages from Lua scripts or built-in checks
- A "Caused by..." summary showing up to three resources that triggered degradation (formatted by `formatHealthCauses`)

### Querying Health via CLI

The `argocd app get` command (implemented in [`cmd/argocd/commands/app.go`](https://github.com/argoproj/argo-cd/blob/main/cmd/argocd/commands/app.go)) displays health status and problematic resources:

```bash
argocd app get my-app --refresh

```

Sample output includes:

```

Health: Degraded
Caused by apps/Deployment:default/nginx-deployment

```

This mirrors the controller's aggregation logic and provides the same visibility as the web interface for automation and debugging scenarios.

## Summary

- Argo CD health status and monitoring rely on the `setApplicationHealth` function in [`controller/health.go`](https://github.com/argoproj/argo-cd/blob/main/controller/health.go) to aggregate resource-level health into application-level status.
- The system prioritizes health statuses in the order: **Healthy → Suspended → Progressing → Missing → Degraded → Unknown**.
- Built-in Go implementations in `gitops-engine/pkg/health/` handle standard Kubernetes resources like Deployments, Services, and Jobs.
- Custom Lua scripts can extend health checks to CRDs via the `argocd-cm` ConfigMap, with support for wildcards using the `doublestar` glob library.
- Resources annotated with `argocd.argoproj.io/ignore-healthcheck: "true"` are excluded from health calculations.
- Both the Argo CD UI and CLI display aggregated health and list up to three resources causing degradation.

## Frequently Asked Questions

### How does Argo CD determine the overall health of an application?

Argo CD evaluates every managed resource using either built-in Go checks or custom Lua scripts, then selects the worst status according to the priority order defined in [`controller/health.go`](https://github.com/argoproj/argo-cd/blob/main/controller/health.go). The `setApplicationHealth` function aggregates these individual statuses, with **Degraded** overriding **Healthy**, and **Missing** overriding **Progressing**, etc.

### Can I ignore specific resources when calculating health status?

Yes. Add the annotation `argocd.argoproj.io/ignore-healthcheck: "true"` to any resource you want excluded from health aggregation. The controller skips these resources in the `setApplicationHealth` function (lines 46-49) before processing health checks.

### How do I write a custom health check for a Kubernetes CRD?

Define a Lua script in the `argocd-cm` ConfigMap under the key `resource.customizations.health.<group>_<kind>`. The script receives the resource object as `obj` and must return a table with `status` and optional `message` fields. You can also place scripts in `resource_customizations/<group>/<kind>/health.lua` for version control.

### What is the priority order for health statuses in Argo CD?

The priority hierarchy from least to most severe is: **Healthy**, **Suspended**, **Progressing**, **Missing**, **Degraded**, **Unknown**. When aggregating, the application inherits the most severe status among its resources. This ensures that a single failing resource (Degraded) immediately surfaces in the application health, even when other resources are healthy.