Bug: enableHpaFilter does not filter workloads managed by a memory-based HPA
Component: kubex-automation-engine / AutomationStrategy safety checks (spec.safetyChecks.enableHpaFilter)
Severity: High — automation engine actively resizes HPA-managed workloads it should skip
Description
enableHpaFilter: true fails to filter a workload that has an HPA with a memory utilization target. The filter is set, the HPA exists and is actively managing the workload, yet kubex generates and applies resize recommendations regardless.
Environment
- kubex-automation-engine:
0.1.1
- Kubernetes: EKS (v1.31)
Steps to Reproduce
- Create a
StatefulSet (my-hpa-app) in a namespace (my-namespace)
- Create an HPA targeting it with
targetMemoryUtilizationPercentage set — the Kubernetes API server normalises scaleTargetRef.kind to lowercase for StatefulSet targets regardless of what is submitted
- Create an
AutomationStrategy with safetyChecks.enableHpaFilter: true
- Create a
ProactivePolicy scoping the StatefulSet
Observed Behaviour
The automation engine ignores the HPA and generates resize recommendations for the workload. Pod annotations confirm active rightsizing is being applied:
"proactive.rightsizing.kubex.ai/desired-resource-limits": {
"my-hpa-app": { "cpu": "42870m", "memory": "43430Mi" }
}
Confirming the filter is enabled in the live strategy:
$ kubectl get automationstrategy my-strategy -n my-namespace \
-o jsonpath='{.spec.safetyChecks.enableHpaFilter}'
true
Confirming the HPA exists, targets the workload, and has a memory utilization target:
$ kubectl get hpa my-hpa-app -n my-namespace -o jsonpath='{.spec.scaleTargetRef}'
{"apiVersion":"apps/v1","kind":"statefulset","name":"my-hpa-app"}
$ kubectl get hpa my-hpa-app -n my-namespace -o jsonpath='{.spec.metrics}'
[{"resource":{"name":"memory","target":{"averageUtilization":60,"type":"Utilization"}},"type":"Resource"}]
Expected Behaviour
enableHpaFilter: true should prevent kubex from resizing workloads whose memory is already managed by an HPA — modifying memory requests directly changes the HPA trigger threshold and undermines horizontal scaling behaviour.
Possible Cause
Inspecting the HPA, the scaleTargetRef.kind is lowercase (statefulset):
scaleTargetRef:
apiVersion: apps/v1
kind: statefulset # lowercase
name: my-hpa-app
We attempted to patch this to StatefulSet (PascalCase) to test the theory, but the Kubernetes API server normalises the value back to lowercase on write — it cannot be changed. This is not a helm chart quirk; it is how the Kubernetes HPA API stores scaleTargetRef.kind for StatefulSet targets.
It is likely the HPA filter performs a case-sensitive match on scaleTargetRef.kind and fails to recognise statefulset as matching the StatefulSet workload. Since this normalisation is enforced by the API server, the filter must handle lowercase kinds — there is no client-side workaround.
We cannot confirm this is the root cause without access to the engine source, but it is the most likely explanation given the evidence.
VPA Filter Comparison
enableVpaFilter appears unaffected — VPA objects in the same namespace use PascalCase targetRef.kind and are correctly filtered. This is consistent with a case-sensitivity issue specific to HPA matching.
Workaround
Explicitly exclude HPA-managed workloads from the ProactivePolicy scope using a NotIn label selector rather than relying on enableHpaFilter:
scope:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: NotIn
values:
- my-hpa-app
Bug:
enableHpaFilterdoes not filter workloads managed by a memory-based HPAComponent:
kubex-automation-engine/AutomationStrategysafety checks (spec.safetyChecks.enableHpaFilter)Severity: High — automation engine actively resizes HPA-managed workloads it should skip
Description
enableHpaFilter: truefails to filter a workload that has an HPA with a memory utilization target. The filter is set, the HPA exists and is actively managing the workload, yet kubex generates and applies resize recommendations regardless.Environment
0.1.1Steps to Reproduce
StatefulSet(my-hpa-app) in a namespace (my-namespace)targetMemoryUtilizationPercentageset — the Kubernetes API server normalisesscaleTargetRef.kindto lowercase for StatefulSet targets regardless of what is submittedAutomationStrategywithsafetyChecks.enableHpaFilter: trueProactivePolicyscoping the StatefulSetObserved Behaviour
The automation engine ignores the HPA and generates resize recommendations for the workload. Pod annotations confirm active rightsizing is being applied:
Confirming the filter is enabled in the live strategy:
Confirming the HPA exists, targets the workload, and has a memory utilization target:
Expected Behaviour
enableHpaFilter: trueshould prevent kubex from resizing workloads whose memory is already managed by an HPA — modifying memory requests directly changes the HPA trigger threshold and undermines horizontal scaling behaviour.Possible Cause
Inspecting the HPA, the
scaleTargetRef.kindis lowercase (statefulset):We attempted to patch this to
StatefulSet(PascalCase) to test the theory, but the Kubernetes API server normalises the value back to lowercase on write — it cannot be changed. This is not a helm chart quirk; it is how the Kubernetes HPA API storesscaleTargetRef.kindfor StatefulSet targets.It is likely the HPA filter performs a case-sensitive match on
scaleTargetRef.kindand fails to recognisestatefulsetas matching theStatefulSetworkload. Since this normalisation is enforced by the API server, the filter must handle lowercase kinds — there is no client-side workaround.We cannot confirm this is the root cause without access to the engine source, but it is the most likely explanation given the evidence.
VPA Filter Comparison
enableVpaFilterappears unaffected — VPA objects in the same namespace use PascalCasetargetRef.kindand are correctly filtered. This is consistent with a case-sensitivity issue specific to HPA matching.Workaround
Explicitly exclude HPA-managed workloads from the
ProactivePolicyscope using aNotInlabel selector rather than relying onenableHpaFilter: