diff --git a/.changes/unreleased/operator-Fixed-20260423-224719.yaml b/.changes/unreleased/operator-Fixed-20260423-224719.yaml new file mode 100644 index 000000000..47a906644 --- /dev/null +++ b/.changes/unreleased/operator-Fixed-20260423-224719.yaml @@ -0,0 +1,4 @@ +project: operator +kind: Fixed +body: Fixed an issue where in-use features from an enterprise cluster did not have deterministic sort order and could cause reconciliation storms due to status changes. +time: 2026-04-23T22:47:19.373877-04:00 diff --git a/operator/internal/controller/redpanda/redpanda_controller.go b/operator/internal/controller/redpanda/redpanda_controller.go index 03cecaca3..b773fdf8a 100644 --- a/operator/internal/controller/redpanda/redpanda_controller.go +++ b/operator/internal/controller/redpanda/redpanda_controller.go @@ -14,6 +14,7 @@ import ( "bytes" "context" "fmt" + "sort" "strings" "time" @@ -673,6 +674,10 @@ func (r *RedpandaReconciler) reconcileLicense(ctx context.Context, state *cluste inUseFeatures = append(inUseFeatures, feature.Name) } } + // features.Features iterates a map under the hood; sort the + // resulting slice so repeated reconciles produce byte-identical + // status. + sort.Strings(inUseFeatures) status := &redpandav1alpha2.RedpandaLicenseStatus{ InUseFeatures: inUseFeatures,