#5809·flux2

Inconsistent requeue strategy for missing dependency-like references

Author: matheuscscpCreated Apr 3, 2026Updated Sep 1, 2026
Labelsbug

Describe the bug

When a controller is waiting for a dependency-like resource to appear (source object, valuesFrom ConfigMap/Secret, substituteFrom ConfigMap/Secret), the requeue strategy is inconsistent with how dependsOn and "source exists but not ready" are handled.

Both helm-controller and kustomize-controller use --requeue-dependency for dependsOn not-ready and source-exists-but-artifact-missing, but use different (worse) strategies for other "waiting for a resource" scenarios.

helm-controller

Scenario Requeue strategy
dependsOn not ready --requeue-dependency
Source exists but not ready --requeue-dependency
Artifact fetch file not found --requeue-dependency
Source object not found (chartRef) exponential backoff
valuesFrom not found exponential backoff

Source object not found (helmrelease_controller.go#L288-L290):

go
msg := fmt.Sprintf("could not get Source object: %s", err.Error())
conditions.MarkFalse(obj, meta.ReadyCondition, v2.ArtifactFailedReason, "%s", msg)
return ctrl.Result{}, err

valuesFrom not found (helmrelease_controller.go#L318-L320):

go
conditions.MarkFalse(obj, meta.ReadyCondition, "ValuesError", "%s", err)
r.Eventf(obj, corev1.EventTypeWarning, "ValuesError", err.Error())
return ctrl.Result{}, err

kustomize-controller

Scenario Requeue strategy
dependsOn not ready --requeue-dependency
Source artifact nil --requeue-dependency
Artifact fetch file not found --requeue-dependency
Source object not found retryInterval
substituteFrom not found retryInterval

Source object not found (kustomization_controller.go#L214-L217):

go
if apierrors.IsNotFound(err) {
    msg := fmt.Sprintf("Source '%s' not found", obj.Spec.SourceRef.String())
    log.Info(msg)
    return ctrl.Result{RequeueAfter: obj.GetRetryInterval()}, nil
}

substituteFrom not found — caught as a general reconcile error (kustomization_controller.go#L289-L297):

go
if reconcileErr != nil {
    log.Error(reconcileErr, fmt.Sprintf("Reconciliation failed after %s, next try in %s",
        time.Since(reconcileStart).String(),
        obj.GetRetryInterval().String()),
        "revision",
        revision)
    r.event(obj, revision, originRevision, eventv1.EventSeverityError,
        reconcileErr.Error(), nil)
    return ctrl.Result{RequeueAfter: obj.GetRetryInterval()}, nil
}

Expected behavior

All "waiting for a dependency-like resource to exist" scenarios should requeue with --requeue-dependency, consistent with dependsOn not-ready and source-not-ready handling.

Use case

This matters when resources are deployed together in the same sync path (e.g. via a ResourceSet). A HelmRelease may reference a valuesFrom ConfigMap generated by a Kustomize configMapGenerator, or a chartRef OCIRepository — these may not exist yet when the HelmRelease is first reconciled. Exponential backoff (or the full retry/reconcile interval) delays the eventual reconciliation unnecessarily compared to the short --requeue-dependency interval.