Why an Argo CD application stays Progressing and how to find the resource holding it
An Argo CD application that shows Progressing and never reaches Healthy is almost always waiting on one resource that does not report healthy. Argo CD computes health per resource, then rolls the results up to the application, so the fix starts by finding which child resource is holding the status. Open the application in the UI, select the resource tree, and look for the item whose health icon is not green. Health is a separate assessment from sync status: an application can be Synced to Git and still be unhealthy, and a resource can be healthy while the application is OutOfSync. Keep those two questions apart when you read the page.
Progressing means Argo CD has seen the resource and expects it to converge, such as a Deployment still rolling out new pods. Degraded means the resource has reported a failure, such as a pod in CrashLoopBackOff or an Ingress with an error. Missing means the resource is declared in Git but does not exist in the cluster. Progressing is the state most often confused with a healthy rollout that is simply slow, so decide whether the resource is still moving or has stopped. The Argo CD FAQ lists Ingress, StatefulSet and SealedSecret resources as common reasons an application stays Progressing. Custom resources without a health check are also a frequent cause, because Argo CD does not know how to judge their status and falls back to a status it cannot interpret.
Confirm the exact health check that applies before changing anything. The built-in checks cover standard Kubernetes kinds, while CRDs depend on a Lua health check in argocd-cm or a bundled check from your installation. The Argo CD resource health documentation explains how these checks are written and where they are configured. Record which resource is responsible, which check evaluated it, and what its status block reports. That evidence determines whether the problem sits in the workload, the cluster, the controller that owns the resource, or the health configuration itself.
Which resource is usually holding the application in Progressing
Argo CD marks an Ingress as Healthy only after the ingress controller has published an address in its status. On clusters where no load balancer or ingress controller assigns that address, the Ingress stays Progressing indefinitely even though the manifest applied cleanly. The Argo CD FAQ lists Ingress among the common reasons an application stays Progressing, so this is usually the first resource to inspect.
- Symptom in the UI: the Ingress node shows a spinner or Progressing status while the Deployment and Service are Healthy.
- Check with kubectl: run
kubectl get ingress -n <namespace> -o wideandkubectl describe ingress <name> -n <namespace>, then look for an empty ADDRESS column or a missingstatus.loadBalancer.ingressentry. - Fix direction: confirm the ingress controller is running and has an external address (for example, a load balancer service or a node-based setup in your environment), and check that the controller watches the Ingress class you set.
- Fix direction for clusters without a load balancer: decide whether to add a custom health check for that Ingress type, or to accept the state with a documented exception rather than hiding it.
- What to confirm: whether your ingress controller publishes addresses in its status on your platform, which you can check with the controller's documentation.
Before changing Argo CD, confirm the controller's status update path works, because the health check only reads what Kubernetes reports.
A StatefulSet is Healthy when its pods are updated and ready, and Argo CD waits for that condition during a rollout. A rollout can stay Progressing when pods never become ready, when an update partition holds back some ordinals, or when the controller is waiting on a pod that cannot be scheduled because of storage or affinity. The fix is usually in the workload, not in Argo CD.
- Symptom in the UI: the StatefulSet shows Progressing with a partial replica count, and the pods list shows one or more pods not ready.
- Check with kubectl: run
kubectl rollout status statefulset/<name> -n <namespace>andkubectl get pods -n <namespace> -l <selector>, thenkubectl describe podon the first pod that is not ready. - Look for partitions: check
spec.updateStrategy.rollingUpdate.partitionin the live object, because a partition above zero intentionally leaves some pods on the old revision. - Fix direction: resolve the readiness failure first (probes, image pull, volume binding), then align the partition value in Git with what the team intends.
- Fix direction for intentional holds: if a partition is a deliberate staged rollout, record it in Git so Argo CD does not treat the hold as a permanent fault.
A StatefulSet that waits on storage is often a scheduling issue, so check persistent volume claims alongside the pods.
The Argo CD FAQ names SealedSecret among the resources that commonly leave an application Progressing. Older versions of the Sealed Secrets custom resource did not expose the status fields that Argo CD reads, so the health logic cannot find a condition that says the secret was unsealed. The resource then looks permanently unfinished even though the controller has done its job.
- Symptom in the UI: the SealedSecret node stays Progressing while the decrypted Secret exists in the cluster.
- Check with kubectl: run
kubectl get sealedsecret <name> -n <namespace> -o yamland look atstatus.conditions, then confirm the matching Secret exists withkubectl get secret <name> -n <namespace>. - Check the CRD version: run
kubectl get crd sealedsecrets.bitnami.com -o yamland compare the served versions and schema with the release notes of your installed controller. - Fix direction: upgrade the Sealed Secrets controller and its CRD to a version that reports status conditions, then let Argo CD refresh the application.
- Fix direction if upgrading is delayed: add a Lua health check for the SealedSecret that reads the conditions your version actually sets.
Confirm the expected status fields for your controller version before writing a health check, since a wrong assumption recreates the problem.
Argo CD knows how to judge built-in Kubernetes kinds, but it has no built-in logic for most custom resources. For a custom resource without a health check, Argo CD falls back to a generic result that can stay Progressing, which often surprises teams that installed an operator. The fix is to tell Argo CD what Healthy means for that kind, using a Lua health script in the argocd-cm ConfigMap.
- Symptom in the UI: a custom object in the resource tree is Progressing while the operator reports it as ready in its own logs or events.
- Check with kubectl: run
kubectl get <kind> <name> -n <namespace> -o yamland read the status block, then confirm which condition the operator sets when reconciliation finishes. - Fix direction: add a
resource.customizations.health.<group>_<kind>entry toargocd-cm, returning Healthy, Progressing or Degraded from the conditions you found. - Fix direction for operators with published checks: check whether the operator's project documents a health script before writing one, and keep the script under version control.
- What to test: create or update the resource in a non-production cluster and confirm each state transition appears as expected in the UI.
An untested script can make a healthy resource look broken, so verify each path before rolling it out.
A Lua health check that reads only the current status can flip between Healthy and Progressing as the controller updates the object. The Argo CD health guide recommends basing custom Lua checks on observedGeneration, so the check only reports Healthy when the status describes the spec that is currently applied. Without that comparison, a check may read a stale Ready condition from the previous generation during a change, and then a new value shows the resource as not ready again.
- Symptom in the UI: the application alternates between Healthy and Progressing, and the resource's health history shows repeated transitions with no real outage.
- Check with kubectl: run
kubectl get <kind> <name> -n <namespace> -o jsonpath='{.metadata.generation} {.status.observedGeneration}'and compare the two numbers during a change. - Fix direction: update the Lua script so it returns Healthy only when
status.observedGenerationequalsmetadata.generationand the ready condition is true. - Fix direction for transient states: return Progressing explicitly while the generations differ, so the state is intentional rather than accidental.
- What to test: apply a change to the resource and watch the Argo CD UI until it settles, then repeat with an invalid value to confirm Degraded appears.
If the status never catches up to the generation, the operator is stuck, and the health check is reporting a real problem.
How to diagnose the resource that never turns Healthy
This sequence narrows an application stuck in Progressing down to the one resource whose health never reaches Healthy, and to the reason it stays there. The output is a named resource, a confirmed cause and a decision about whether the fix belongs in the manifest or in the health check.
Open the application resource tree
Open the application in the Argo CD UI, or run the argocd CLI command for the application, and expand the resource tree. Note every node whose health shows Progressing or Missing, and separate them from nodes that are Healthy or only out of sync. Check that the application is Progressing rather than Degraded, because the two states point to different causes. Done when you have a short list of named resources, each with its kind, namespace and health state.
Identify the single blocking resource
Parent resources such as Deployments and Applications often show Progressing only because a child is not yet ready. Follow the tree down from the top-level node to the lowest resource that reports Progressing or Missing, and treat that resource as the candidate. Ignore resources that are Healthy even if they are OutOfSync. Done when you can name one resource that has no unhealthy child of its own.
Describe the resource and read its status
Run kubectl describe on the candidate in its namespace, and read the Status and Conditions section, along with any message fields on the conditions. For an Ingress, look for a load balancer address in status; for a StatefulSet, compare ready and updated replica counts; for a custom resource, look for a Ready or similar condition. Done when you have written down the exact condition type, its status and its message, because that text usually names the missing dependency.
Compare generation with observedGeneration
Read metadata.generation and status.observedGeneration on the candidate. If observedGeneration is lower than generation, the controller has not processed the latest spec yet, so wait for it to catch up and check its logs before blaming the manifest. If they match but the condition still reports not ready, the controller has seen the change and is waiting on something else. Done when you know whether the controller is behind or has finished reconciling and is reporting a real state.
Check controller events and pod status
Run kubectl get events in the namespace, sorted by time, and check the pods owned by the candidate with kubectl get pods and kubectl describe pod. Look for scheduling failures, image pull errors, failing readiness probes and CrashLoopBackOff states. For a StatefulSet, confirm whether pods are waiting on a predecessor or on a volume claim. Done when you can tie the blocking condition to a specific event or pod state.
Confirm the cause against the health check
Decide whether the resource is genuinely not ready, or whether Argo CD is evaluating health for a kind it does not understand. Check whether the resource has a built-in health check, a custom Lua check in argocd-cm, or no check at all. For Lua checks, confirm the script reads observedGeneration and returns the status it should. Done when you have one stated cause, either a workload or dependency problem or a health check problem, written down before any change.
Fix the manifest or health check, not the sync
Apply the change in the Git source for the manifest, such as a missing dependency or corrected rollout settings, or in the health check configuration if the check is wrong. Avoid forcing a sync to clear the state, because a sync re-applies the same spec and leaves the cause in place. Commit the change, let Argo CD reconcile it, and confirm the resource moves to Healthy and the application status follows. Done when the blocking resource reports Healthy after reconciliation from Git.
Writing Lua health checks that do not flap
A custom Lua health check decides whether Argo CD ever reports a custom resource as Healthy. The decisions below determine whether that verdict is accurate and stable across reconciliations. Work through them in order before you put a check into production.
Choose the fields that define readiness
Start from the status fields the controller for the custom resource actually writes, such as conditions with a type and status, or a phase value. Confirm these names against the resource's CRD and its controller documentation rather than assuming them. A check built on fields the controller updates late will report stale health, while a check built on transient fields will flip between states. Record which field means ready and which means failed before writing any Lua.
Compare observedGeneration with generation
Before reporting Healthy, confirm that the controller has processed the latest spec by comparing the status observedGeneration with the object's metadata generation. Without this guard, the check can read the status from the previous spec and report Healthy while a new rollout is still pending. Treat a mismatch as Progressing. This comparison is the main protection against health flapping on complex CRDs that the health guide describes.
Decide when to return Progressing or Degraded
Return Progressing when the resource is still converging, for example while conditions are unknown or the generation has not caught up. Return Degraded only for a terminal failure that an operator must act on, such as a condition that reports an error the controller will not retry. Mixing these up causes either false alarms during normal rollouts or failures that never surface. Write down the condition values that map to each state and review them with the team that owns the CRD.
Test against real resource states
Capture live objects in several states, including a fresh create, a steady ready state, a spec change in progress, and a failed reconcile, then run the check against each one. Use the Argo CD health documentation for the exact Lua runtime behavior in your version, and confirm syntax there before testing. A check that passes only on a healthy example has not been verified against the transitions where flapping happens.
Store the check in argocd-cm
Custom health checks live in the argocd-cm ConfigMap, keyed by the resource group and kind, and are applied when the configuration changes. Keep the Lua in version control with the rest of the Argo CD configuration so changes go through review. After each change, confirm that affected applications reevaluate and that the new verdicts match your test states, and confirm the exact key format in the health documentation for your Argo CD version.
When a stuck Progressing status needs a platform owner, not a quick fix
When many applications sit in Progressing at the same time, the cause is usually outside any one application. Check whether the stall is confined to a single cluster, a single repository or a single controller shard before touching a manifest. Widespread stalls can point to application controller load, repo-server saturation or a problem with Redis. The high availability documentation describes Redis as a disposable cache, so a flushed or restarted Redis should rebuild its state rather than hold the answer. The platform owner should look at controller and repo-server logs, resource pressure and recent changes to the Argo CD installation itself, and should confirm the exact component behavior against the high availability documentation for the version in use.
Some stuck states trace back to cluster-wide objects. A changed CustomResourceDefinition, a new admission webhook or a modified ClusterRole can alter how many applications are evaluated, so treat these as platform changes with their own review. Argo CD's RBAC changes also deserve scrutiny, because a role that can no longer read a resource or its logs will show up as an unhealthy application even though nothing is wrong with the workload. Confirm which teams own the CRDs, webhooks and Argo CD RBAC in your organization before anyone edits them under pressure.
Repairs on production clusters should follow the same Git change path as every other change. A quick kubectl patch may clear the symptom for one application, but Argo CD will either revert it on the next sync or leave the live state out of step with the repository, which is harder to audit later. Record the fix as a commit, route it through the approval steps your change process requires, and keep a rollback plan. Ask any external partner to deliver repairs the same way, with a written scope and a change record for each step.
Security and change control while debugging stuck applications
Debugging a stuck application means touching live clusters, logs and the repo-server, and each of those actions carries its own risk. The cards below cover the permissions you grant yourself, the live edits Git will undo, health checks that can hide failures, and the repo-server exposure that comes from rendering repository content. Work through them before you change anything in the cluster.
Scope debugging permissions tightly
Broad cluster-admin access or a全-project admin role makes it easy to fix symptoms in place and hard to prove what changed. Give yourself read access to the Application, its child resources and the controller events first. Since the 2.14 to 3.0 upgrade, update and delete RBAC applies only to the application itself, and logs access needs an explicit logs, get permission. Confirm both in your project policy before an incident, not during one.
Logs access can block your diagnosis
Pod logs are often the fastest way to see why a Deployment or StatefulSet never settles. Because logs access now requires an explicit logs, get grant, an engineer with application read access may see the Progressing status but not the container output that explains it. Check this grant for on-call roles while you are validating your RBAC, so the people paged at night can see what they need without wider rights.
Live edits that Git overwrites
Patching a Service, Ingress or StatefulSet with kubectl during debugging looks like a fix until the next sync reverts it, and Argo CD will show the resource as OutOfSync again. Record every live change you make, then commit the fix to Git or revert it before the next sync. A live edit that stays in the cluster is undocumented drift that a later change will silently erase.
Lua checks that hide failures
A custom Lua health check that returns Healthy too early, or that swaps between states, can mask a real fault or create a false alarm. Base the check on observedGeneration so it reads status for the current spec, and test it against both a healthy and a failed resource before you rely on it. Treat any change to a health script as a reviewed change, since it alters what every team sees as healthy.
Repo-server exposure from rendered content
The repo-server runs Helm and Kustomize against repository content, so a malicious chart, values file or Kustomize build can read or affect files it should not reach. While debugging, prefer rendering manifests from a trusted branch and avoid pointing applications at untested forks. Confirm which repositories are allowed in your AppProjects and whether out-of-tree file access is restricted, as the security documentation advises.
Credentials and API calls stay protected
Argo CD authenticates API requests only with JSON Web Tokens and redacts cluster, Git and OAuth2 credentials from API responses and logs, so logs you copy into a ticket should not reveal those secrets. Still, avoid pasting full manifests that include tokens or annotations you have not reviewed. Ask your team to rotate any token that was shared in a chat or ticket during the incident.
Fix options and when each one fits
This table compares four ways to resolve an application stuck in Progressing: correcting the manifest, adding a custom health check, overriding health for one resource kind, and marking a resource as not health-relevant. Read each row by asking whether the resource is genuinely broken, whether Argo CD misjudges a healthy object, and how much the fix hides. The main takeaway is that only the first option removes a real fault, so confirm the cause before choosing any of the others.
| Fix path | When it fits | Risk | What to confirm in the health documentation |
|---|---|---|---|
| Correct the manifest | The Ingress, StatefulSet or other resource is truly not converging, for example an Ingress with no load balancer address or a StatefulSet pod stuck in a failing rollout | Low if the root cause is fixed; the application becomes Healthy only when the object actually reaches its ready state | Which built-in health check applies to the kind and what fields it reads, such as the status conditions Argo CD evaluates |
| Add a custom Lua health check in argocd-cm | A custom resource kind has no built-in check, and its status reliably reports readiness through conditions or observedGeneration | Medium: a script that reads the wrong field can mark a broken object Healthy or flap between states | The resource.customizations.health key format for the group and kind, and the Lua return values for Healthy, Progressing, Degraded and Unknown |
| Health override for a specific resource kind | One kind in one installation needs different evaluation, and the team can show which status field is authoritative | Medium: overrides apply cluster-wide for that kind, so a wrong rule affects every application that contains it | Whether the override belongs in argocd-cm or an equivalent setting for your Argo CD version, and how it interacts with an existing custom check for the same kind |
| Accept the resource as not health-relevant | The object is informational, such as a helper resource with no runtime state, and its health does not reflect application readiness | High if misused: marking a workload resource as ignored can hide a failed deployment behind an apparently Healthy application | Whether the health setting that excludes a resource from the application health rollup is available in your version, and how the exclusion is recorded in Git |
| Flapping check fix (observedGeneration) | A Lua check reports Healthy and Progressing alternately during reconciliation | Low to medium: comparing generation values fixes the flapping but needs a correct status schema | That the controller updates status.observedGeneration for the CRD, and that the check waits until it matches metadata.generation |
Setting up a verified fix for a stuck application
This sequence turns a guessed health check into a tested change: you reproduce the Progressing state safely, confirm the cause from live status, and ship the fix through Git. It ends only when the application holds Healthy across several reconciliations and the change is on record.
Reproduce the stuck state in a non-production application
The platform engineer who owns the application deploys the same manifests to a non-production Argo CD application, ideally in a cluster that matches production's resource types and controllers. Confirm the first symptom before changing anything: the application shows Progressing and the suspect resource shows the same health message as production. If the non-production copy becomes Healthy on its own, the cause is environmental, such as a controller present only in production, and the fix belongs somewhere else.
Capture the resource status and generation
Use the Argo CD UI or the argocd CLI to open the resource tree, then read the live object with kubectl. Record the status conditions, the metadata.generation value, and the status.observedGeneration value the controller has reported. A gap between generation and observedGeneration means the controller has not processed the latest spec, which points to a stalled controller rather than a health rule. Save this output with the change ticket so the before and after states can be compared.
Write or correct the health check in Git
Write the Lua health check in the Argo CD configuration that your installation manages from Git, keyed to the resource's group and kind. For custom resources, base the check on observedGeneration so that a stale status never reports Healthy and a fresh one is not left Progressing. Confirm where your installation stores argocd-cm settings: in a Helm values file, a Kustomize overlay, or directly in the cluster. If the setting lives only in the cluster, bring it under Git control before changing it, or the next sync from another source may overwrite it.
Sync the change through the normal review path
Open a pull request with the health check change and the non-production evidence, get it reviewed by someone outside the change author, and merge it. Let the Argo CD application that manages the Argo CD configuration sync the change, then confirm the controller has reloaded it by checking the configuration resource and the controller logs for the new check. Do not patch the live configMap by hand as the final step, because that produces drift in the Argo CD configuration itself.
Confirm the application reaches Healthy
Trigger a refresh of the affected application and watch its health status and the health of the individual resources. The check passes when the application reports Healthy and the custom resource shows the health value you expected, with the message matching the status you captured earlier. If the state still reads Progressing, compare the resource's status with the rule's logic before editing the rule again.
Watch for flapping across several reconciliations
Leave the application under observation across several reconciliation cycles, including a period with no changes to Git, and record the health status each time. Flapping between Healthy and Progressing or Degraded usually means the rule depends on a field that changes during normal operation, or it does not guard against a stale status. The check passes when the status remains Healthy through the observation window and the resource's generation and observedGeneration stay in agreement. Repeat the test after any controller upgrade, because changes in controller behavior can alter what a rule sees.
Promote and record the change
Apply the same reviewed change to production through the same Git path, then repeat the status capture and health confirmation there. Record the resource, the captured status, the Git commit that added the rule, the non-production and production results, and the observation window in your change system. Auditors and on-call engineers will rely on this record later, so it should name the commit and the people who reviewed it. Once the record is complete, the fix is verified and the next team that hits this resource type can reuse the rule.
Limits to confirm in your environment before you change health checks
Health check changes depend on what your Argo CD version does, which resources your clusters run and who is allowed to edit shared configuration. The cards below cover the limits to confirm before you touch argocd-cm or write a custom check, so a fix for one application does not create drift or flapping across the rest.
Argo CD version and health behavior
Start by confirming the exact Argo CD version in production, since health evaluation rules and built-in checks can change between minor releases. Compare the running version with the release notes before copying a health snippet from a blog post or an older page of the docs. Record the version in your change ticket so a later reader can tell which behavior the check was written against.
CRDs and their status fields
List the custom resource definitions your clusters actually run, including their versions, and check whether each one publishes a status block with conditions or observedGeneration. A CRD that writes no status gives Argo CD nothing to evaluate, so the application stays Progressing even when the workload is running. Confirm this on each cluster, because the same chart can install different CRD versions in different environments.
Upstream health checks for the resource
Before writing a custom check, confirm whether the resource already has a health check in the Argo CD project or in a community library you trust. Reusing a maintained check avoids duplicate logic and keeps your edits small. If you do write one, test it against a healthy object, a degraded object and an object mid-rollout in a non-production cluster.
Patch support and upgrade cadence
Argo CD patch releases cover only the three most recent minor versions, so a health fix that works on an unsupported version may never get a bug fix. Agree with your platform owners how quickly you move to a supported minor release and who tests a health check after each upgrade. Confirm the upgrade window before you rely on a configuration that a later release may change.
Change control for argocd-cm
Health checks live in the argocd-cm ConfigMap, which is shared by every application on the instance, so one bad Lua script can affect many apps at once. Confirm whether your change control allows direct edits to this ConfigMap, who approves them and whether the change must be committed to Git. Ask whether a staged rollout or a second Argo CD instance is available for testing before production.
Questions teams ask before fixing Progressing themselves or hiring help
How long does fixing a stuck Progressing application usually take?
The time depends mostly on how many resource types are involved and how many clusters share the same Argo CD instance. A single Ingress or StatefulSet check is usually quick to diagnose, while a set of custom resources that each need a Lua health check takes longer because every check must be written, tested against real status fields and promoted through Git. Change control adds time when each Git change needs review or a maintenance window. When you request a quote, ask for the number of custom CRDs in scope, the number of clusters and applications affected, and how your change approval process works, then ask for the duration to be written into the fixed scope.
Can our own platform team fix Progressing applications without outside help?
Yes, if the team can read resource status fields in the cluster and write and test Lua health check scripts. Most cases come down to finding which field Argo CD is waiting on, such as an Ingress without a load balancer address, a StatefulSet that has not finished its rollout, an older SealedSecret CRD, or a custom resource with no health check. Start with the Argo CD resource health documentation and a non-production cluster to test each change. Bring in a partner when the number of custom resources is large, when the team lacks Lua experience, or when you need the fixes delivered on a fixed schedule.
What do we need to provide before work starts on a Progressing fix?
A partner needs read access to the affected Argo CD applications and the target clusters so it can inspect resource status, events and the health of each object. It also needs a non-production copy of the environment, or at least a cluster where health check changes can be tested without affecting live workloads. Your Git change process should be defined in advance, including who reviews changes, how they are merged and how Argo CD picks them up. Ask the provider to list these access and environment needs in the written scope before any work begins.
Does a Lua health check fix require an Argo CD upgrade?
Usually not. Custom Lua health checks are defined in the Argo CD configuration and can be added or corrected on the running version, so an upgrade is not required for most fixes. Health checks for complex custom resources should rely on the observedGeneration field so the status does not flap between Healthy and Progressing while the controller is still reconciling. Confirm your installed version and its support status first, because the release process supports only the three most recent minor versions with patch releases. If the installed version is outside that window, plan an upgrade separately.
What does a fixed-scope engagement for this work cover?
A fixed-scope engagement sets out, in writing, which applications, resource types and clusters are included, what diagnosis findings you will receive, which health checks or configuration changes will be delivered, and how each change will be tested. It should also state what is excluded, such as unrelated sync failures or application code problems. Expect a written handover that explains each change and how to check it later. Ask the provider to show the deliverables and acceptance steps in the quote so you can compare it against your own estimate.
When should we add monitoring so stuck applications are caught early?
Add monitoring once the root causes are fixed and each health check has been tested through a normal Git change, so alerts reflect the corrected state. Alerts on applications that remain Progressing for longer than your normal rollout time help catch regressions quickly, especially after new custom resources or Argo CD upgrades are introduced. Alerting on Degraded and OutOfSync counts is a separate design choice that belongs to your operations plan. Ask any partner to define which metrics, thresholds and routing rules will be included in the scope and who will receive each alert.
How DeployOpen scopes and supports Argo CD health fixes
DeployOpen approaches stuck Progressing applications by first identifying which resource never reports Healthy, then fixing the check or the workload behind it inside your own clusters. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
How we scope
- Inventory the applications reporting Progressing and the resource kinds that hold each one back
- Confirm which Ingress, StatefulSet, SealedSecret or custom resources need health logic
- Agree in writing which clusters, Argo CD versions and Git repositories the fix covers
How we build
- Correct Ingress, StatefulSet or CRD health checks, using observedGeneration for custom Lua checks
- Test each health change against a non-production application before it reaches production
- Confirm Lua checks settle to a stable state across repeated reconciliation cycles
How we hand over
- Deliver the health configuration as Git-tracked changes with a short record of each cause
- Document how to read the Argo CD health status for each affected resource kind
- Walk your platform team through the checks so they can review future custom resources
How we support
- Offer ongoing support and upgrade work as a retainer after the fixed-scope fix is complete
- Re-check health behavior when Argo CD releases new patch or minor versions you run
- Confirm retainer scope, response expectations and access arrangements with your team in writing

