kubernetes-sigs / kubernetes-sigs/node-readiness-controller

[BUG] ListBlockedNodes incorrectly reports satisfied anyOf nodes as "blocked" in metrics

Open
#458 2 comments 0 reactions 1 assignee View on GitHub

@vishnukothakapu is already working on this.

Since Sep 1, 2026.

kind/bug triage/needs-information
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
  1. Create a NodeReadinessRule with conditionPolicy: anyOf and two conditions (e.g. NetworkReady and StorageReady).
  2. Have a Node satisfy the rule by setting NetworkReady=True but StorageReady=False.
  3. Give the Node the managed taint so that hasTaintBySpec evaluates to true (this simulates a transient pending state or a dryRun evaluation).
  4. Run ListBlockedNodes.
  5. Observe: The function returns StorageReady: 1, indicating the node is blocked by StorageReady, even though the node is fully satisfied by NetworkReady and 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.