kubernetes-sigs / kubernetes-sigs/node-readiness-controller
[BUG] ListBlockedNodes incorrectly reports satisfied anyOf nodes as "blocked" in metrics
@vishnukothakapu is already working on this.
Since Sep 1, 2026.
- Dominant language
- Go
- Stars
- 164
- Forks
- 75
- Avg merge
- 8d 23h
- Merged PRs (30d)
- 13
Description
What happened?
When ListBlockedNodes calculates the rule_blocked_conditions_total metrics, it unconditionally increments the blocked count for every unsatisfied condition on a node that has a taint (held == true).
While this logic is correct for allOf rules (where any unsatisfied condition is indeed blocking the node), it breaks for anyOf rules. If a node satisfies an anyOf rule (i.e. at least one condition is True) but it still currently has the taint (e.g. because it's running in dryRun mode or simply pending reconciliation to remove the taint), ListBlockedNodes incorrectly ignores the satisfied condition and reports that the node is blocked by the other unsatisfied conditions.
This leads to massive metric pollution where perfectly ready and satisfied nodes are falsely reported as "blocked" by conditions that aren't actually blocking them, breaking alerting and observability dashboards.
Steps to Reproduce
- Create a
NodeReadinessRulewithconditionPolicy: anyOfand two conditions (e.g.NetworkReadyandStorageReady). - Have a Node satisfy the rule by setting
NetworkReady=TruebutStorageReady=False. - Give the Node the managed taint so that
hasTaintBySpecevaluates to true (this simulates a transient pending state or adryRunevaluation). - Run
ListBlockedNodes. - Observe: The function returns
StorageReady: 1, indicating the node is blocked byStorageReady, even though the node is fully satisfied byNetworkReadyand is not blocked at all.
Note: This flawed logic is explicitly codified and expected in internal/controller/rule_node_states_test.go within TestListBlockedNodes_AnyOfWithSatisfiedCondition.
Expected Behavior
If ConditionPolicy is anyOf, and at least one condition is satisfied on the node, the node is not blocked. ListBlockedNodes should recognize that the anyOf rule is satisfied and skip incrementing the blocked counts for that node entirely, even if the node still currently holds the taint.
Controller Version / Image Tag
v0.5.0 / main
Kubernetes Version
N/A
Controller Logs
N/A - This is a logic flaw in metric calculation, not a runtime panic.
Additional Environment Details
The fix is straightforward and requires an early return in the onNode callback of ListBlockedNodes (around internal/controller/nodereadinessrule_controller.go:L640) if GetConditionPolicy() == anyOf and anySatisfied is true. The test TestListBlockedNodes_AnyOfWithSatisfiedCondition should also be updated to expect 0 blocked conditions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.