Repository: kubernetes-sigs/kueue

Issue:
[flaky e2e starup] "manager" in "kueue-controller-manager-59598f4b99-pc2h5" has restarted 1 times
/kind flake 

**What happened**:

failure on unrelated branch:  https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/7827/pull-kueue-test-e2e-main-1-34/1992908904400424960

**What you expected to happen**:
no failure
**How to reproduce it (as minimally and precisely as possible)**:

ci 
**Anything else we need to know?**:

```
End To End Suite: kindest/node:v1.34.0: [BeforeSuite] expand_less	34s
{Told to stop trying after 0.007s.
"manager" in "kueue-controller-manager-59598f4b99-pc2h5" has restarted 1 times failed [FAILED] Told to stop trying after 0.007s.
"manager" in "kueue-controller-manager-59598f4b99-pc2h5" has restarted 1 times
In [BeforeSuite] at: /home/prow/go/src/sigs.k8s.io/kueue/test/e2e/singlecluster/suite_test.go:73 @ 11/24/25 11:02:48.53
}
```
and I found the logs:

```
{"AdmissionFairSharing":true,"ConfigurableResourceTransformations":true,"DynamicResourceAllocation":false,"ElasticJobsViaWorkloadSlices":false,"FailureRecoveryPolicy":false,"FlavorFungibility":true,"FlavorFungibilityImplicitPreferenceDefault":false,"HierarchicalCohorts":true,"LendingLimit":true,"LocalQueueDefaulting":true,"LocalQueueMetrics":true,"ManagedJobsNamespaceSelectorAlwaysRespected":true,"MultiKueue":true,"MultiKueueAdaptersForCustomJobs":true,"MultiKueueAllowInsecureKubeconfigs":false,"MultiKueueBatchJobWithManagedBy":true,"MultiKueueClusterProfile":false,"ObjectRetentionPolicies":true,"PartialAdmission":true,"PrioritySortingWithinCohort":true,"PropagateBatchJobLabelsToWorkload":true,"ReclaimablePods":true,"SanitizePodSets":true,"TASBalancedPlacement":false,"TASFailedNodeReplacement":true,"TASFailedNodeReplacementFailFast":true,"TASProfileLeastFreeCapacity":false,"TASProfileMixed":true,"TASReplaceNodeOnPodTermination":true,"TopologyAwareScheduling":true,"VisibilityOnDemand":true,"WorkloadRequestUseMergePatch":false}}
2025-11-24T11:01:07.900702194Z stderr F 2025-11-24T11:01:07.900446511Z	LEVEL(-2)	setup	kueue/main.go:206	K8S Client	{"qps": 50, "burst": 100}
2025-11-24T11:01:07.984863254Z stderr F 2025-11-24T11:01:07.973859483Z	ERROR	setup	kueue/main.go:310	Skipping admission check controller setup: Provisioning Requests not supported (Possible cause: missing or unsupported cluster-autoscaler)	{"error": "no matches for kind \"ProvisioningRequest\" in version \"autoscaling.x-k8s.io/v1\""}
2025-11-24T11:01:07.984933095Z stderr F main.setupIndexes
2025-11-24T11:01:07.984938865Z stderr F 	/workspace/cmd/kueue/main.go:310
2025-11-24T11:01:07.984943295Z stderr F main.main
2025-11-24T11:01:07.984947545Z stderr F 	/workspace/cmd/kueue/main.go:251
2025-11-24T11:01:07.985049507Z stderr F runtime.main
2025-11-24T11:01:07.985056697Z stderr F 	/usr/local/go/src/runtime/proc.go:285
2025-11-24T11:01:07.990253588Z stderr F 2025-11-24T11:01:07.989909494Z	INFO	setup	kueue/main.go:453	Probe endpoints are configured on healthz and readyz
2025-11-24T11:01:07.990631542Z stderr F 2025-11-24T11:01:07.99045343Z	INFO	setup	cert/cert.go:90	Waiting for certificate generation to complete
2025-11-24T11:01:07.990963446Z stderr F 2025-11-24T11:01:07.990746704Z	INFO	setup	kueue/main.go:295	Starting manager
2025-11-24T11:01:07.991855927Z stderr F 2025-11-24T11:01:07.991582444Z	INFO	controller-runtime.metrics	server/server.go:208	Starting metrics server
```
which looks related

Discussion:
@mimowo: cc @mbobrovskyi @mbobrovskyi: Do we have prow logs?@mimowo: Yes, will update the description also
https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/7827/pull-kueue-test-e2e-main-1-34/1992908904400424960@mimowo: fyi, this failure was before merging https://github.com/kubernetes-sigs/kueue/pull/7772@mbobrovskyi: One more failure https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/7845/pull-kueue-test-e2e-multikueue-main/1993207895721775104.@IrvingMg: /assign@IrvingMg: On my first try, I was able to reproduce this error locally. Let's see if it’s just as easy to reproduce in subsequent attempts. In any case, I’ll start looking into it.

```bash
/Users/Irving_Mondragon/Documents/git/kueue/test/e2e/singlecluster/suite_test.go:59
  STEP: Waiting for availability of deployment: "kueue-system/kueue-controller-manager" @ 11/25/25 10:25:25.244
  "level"=0 "msg"="Deployment is available in the cluster" "deployment"={"name"="kueue-controller-manager" "namespace"="kueue-system"} "waitingTime"="1m1.936154916s"
  STEP: Checking no restarts for the controller: "kueue-system/kueue-controller-manager" @ 11/25/25 10:26:27.184
  [FAILED] in [BeforeSuite] - /Users/Irving_Mondragon/Documents/git/kueue/test/e2e/singlecluster/suite_test.go:73 @ 11/25/25 10:26:27.196
[BeforeSuite] [FAILED] [61.951 seconds]
[BeforeSuite] 
/Users/Irving_Mondragon/Documents/git/kueue/test/e2e/singlecluster/suite_test.go:59

  [FAILED] Told to stop trying after 0.012s.
  "manager" in "kueue-controller-manager-b8789887d-gvnsj" has restarted 1 times
  In [BeforeSuite] at: /Users/Irving_Mondragon/Documents/git/kueue/test/e2e/singlecluster/suite_test.go:73 @ 11/25/25 10:26:27.196
```@mimowo: https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/7859/pull-kueue-test-e2e-main-1-33/1993296869014376448@mimowo: I have an idea, if you are able to repro the problem, but the investigation if hard due to lost logs after container restart, then I think we can just change the `restartPolicy: Never` in https://github.com/kubernetes-sigs/kueue/blob/main/config/components/manager/manager.yaml
Then when the issue happens, then instead of restarting the container the whole pod is recreated. As a result we should get the Kueue logs recorded in artifacts for investigation.

Ah, but then the test may just pass rather than fail, as the container will not restart - the whole pod would be recreated (but I'm not sure).

Alternative is to inspect the exit containers on Kind using probably `docker exec -it kind-worker crictl -a` (iirc -a includes exit containers)

EDIT: trying a quick check: https://github.com/kubernetes-sigs/kueue/pull/7892

EDIT2: it will not work: https://github.com/kubernetes-sigs/kueue/pull/7892#issuecomment-3576899682@mimowo: Ok, I think I know what is going on - livenessProbe kills the Pod after ~1min. 

Our configuration of the liveness prove is:
```yaml
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 8081
              scheme: HTTP
            initialDelaySeconds: 15
            periodSeconds: 20
            successThreshold: 1
            timeoutSeconds: 1
```
so iiuc  `initialDelaySeconds + periodSeconds` * `failureThreshold` gives around 55s of runtime, but probably there are some extra delays which make it around 1min.

In kubelet logs we see: https://storage.googleapis.com/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/7859/pull-kueue-test-e2e-main-1-33/1993296869014376448/artifacts/run-test-e2e-singlecluster-1.33.4/kind-worker2/kubelet.log
```
Nov 25 12:43:55 kind-worker2 kubelet[230]: I1125 12:43:55.649262     230 kuberuntime_manager.go:1107] "Message for Container of pod" containerName="manager" containerStatusID={"Type":"containerd","ID":"eb41fdf666294105b7e9d89a58636eb24b98fd279116b94b0db26c9e979b1dc6"} pod="kueue-system/kueue-controller-manager-c674868fd-5mrvp" containerMessage="Container manager failed liveness probe, will be restarted"
```
and we see exactly 3 logs matching `"Probe failed" probeType="Liveness"`

Also, here we have both containers preserved: https://gcsweb.k8s.io/gcs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/7859/pull-kueue-test-e2e-main-1-33/1993296869014376448/artifacts/run-test-e2e-singlecluster-1.33.4/kind-worker2/pods/kueue-system_kueue-controller-manager-c674868fd-5mrvp_dd1677d1-d00b-459c-8345-9db1c657f911/manager/ and we see that the new one was started 59s.

Solution ideas:

1. I think this issue is now more common as we introduced the bootstrap manager, because it does not register the health probe (checked by the liveness probe). So I think registering the health check in the bootstrap container should help. There will only be a small blip between the managers, but it will not fail the probe 3 times in a row.

2. use startupProbe which seems to be designed for similar cases of long startup, but I think this is a change to yaml which isn't really necessary. I think when the bootstrap manager is working the container is healthy, it is just not fully operational yet, but this is another probe - the readiness probe.

So I think (1.) is better.

Solution patch:
diff --git a/go.mod b/go.mod
index 884eb65d1..bb6ab4d91 100644
--- a/go.mod
+++ b/go.mod
@@ -24,19 +24,19 @@ require (
 	go.uber.org/zap v1.27.1
 	golang.org/x/exp v0.0.0-20250718183923-645b1fa84792
 	golang.org/x/sync v0.18.0
-	k8s.io/api v0.34.1
-	k8s.io/apiextensions-apiserver v0.34.1
-	k8s.io/apimachinery v0.34.1
-	k8s.io/apiserver v0.34.1
+	k8s.io/api v0.34.2
+	k8s.io/apiextensions-apiserver v0.34.2
+	k8s.io/apimachinery v0.34.2
+	k8s.io/apiserver v0.34.2
 	k8s.io/autoscaler/cluster-autoscaler/apis v0.0.0-20240830133931-adfbe7e45277
-	k8s.io/cli-runtime v0.34.1
-	k8s.io/client-go v0.34.1
-	k8s.io/component-base v0.34.1
-	k8s.io/component-helpers v0.34.1
+	k8s.io/cli-runtime v0.34.2
+	k8s.io/client-go v0.34.2
+	k8s.io/component-base v0.34.2
+	k8s.io/component-helpers v0.34.2
 	k8s.io/klog/v2 v2.130.1
 	k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912
-	k8s.io/kubectl v0.34.1
-	k8s.io/metrics v0.34.1
+	k8s.io/kubectl v0.34.2
+	k8s.io/metrics v0.34.2
 	k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
 	sigs.k8s.io/cluster-inventory-api v0.0.0-20251028164203-2e3fabb46733
 	sigs.k8s.io/controller-runtime v0.22.4
@@ -145,9 +145,9 @@ require (
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/code-generator v0.34.1 // indirect
+	k8s.io/code-generator v0.34.2 // indirect
 	k8s.io/gengo/v2 v2.0.0-20250820003526-c297c0c1eb9d // indirect
-	k8s.io/kms v0.34.1 // indirect
+	k8s.io/kms v0.34.2 // indirect
 	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 // indirect
 	sigs.k8s.io/gateway-api v1.4.0 // indirect
 	sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
diff --git a/go.sum b/go.sum
index bf7ae08d5..5700dc045 100644
--- a/go.sum
+++ b/go.sum
@@ -378,40 +378,40 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
-k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
-k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI=
-k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
-k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
-k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
-k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA=
-k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0=
+k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY=
+k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw=
+k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo=
+k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE=
+k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
+k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
+k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE=
+k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI=
 k8s.io/autoscaler/cluster-autoscaler/apis v0.0.0-20240830133931-adfbe7e45277 h1:BibFadVS+A7XR6HMReIuHoY9n8I+8oWR8/4xGgf2BDE=
 k8s.io/autoscaler/cluster-autoscaler/apis v0.0.0-20240830133931-adfbe7e45277/go.mod h1:VJdfvO7iPTPM/zc5zjFFvIH3zXZKPAEItzRAB/gZrwA=
-k8s.io/cli-runtime v0.34.1 h1:btlgAgTrYd4sk8vJTRG6zVtqBKt9ZMDeQZo2PIzbL7M=
-k8s.io/cli-runtime v0.34.1/go.mod h1:aVA65c+f0MZiMUPbseU/M9l1Wo2byeaGwUuQEQVVveE=
-k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
-k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
-k8s.io/code-generator v0.34.1 h1:WpphT26E+j7tEgIUfFr5WfbJrktCGzB3JoJH9149xYc=
-k8s.io/code-generator v0.34.1/go.mod h1:DeWjekbDnJWRwpw3s0Jat87c+e0TgkxoR4ar608yqvg=
-k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A=
-k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0=
-k8s.io/component-helpers v0.34.1 h1:gWhH3CCdwAx5P3oJqZKb4Lg5FYZTWVbdWtOI8n9U4XY=
-k8s.io/component-helpers v0.34.1/go.mod h1:4VgnUH7UA/shuBur+OWoQC0xfb69sy/93ss0ybZqm3c=
+k8s.io/cli-runtime v0.34.2 h1:cct1GEuWc3IyVT8MSCoIWzRGw9HJ/C5rgP32H60H6aE=
+k8s.io/cli-runtime v0.34.2/go.mod h1:X13tsrYexYUCIq8MarCBy8lrm0k0weFPTpcaNo7lms4=
+k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M=
+k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE=
+k8s.io/code-generator v0.34.2 h1:9bG6jTxmsU3HXE5BNYJTC8AZ1D6hVVfkm8yYSkdkGY0=
+k8s.io/code-generator v0.34.2/go.mod h1:dnDDEd6S/z4uZ+PG1aE58ySCi/lR4+qT3a4DddE4/2I=
+k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ=
+k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM=
+k8s.io/component-helpers v0.34.2 h1:RIUGDdU+QFzeVKLZ9f05sXTNAtJrRJ3bnbMLrogCrvM=
+k8s.io/component-helpers v0.34.2/go.mod h1:pLi+GByuRTeFjjcezln8gHL7LcT6HImkwVQ3A2SQaEE=
 k8s.io/gengo/v2 v2.0.0-20250820003526-c297c0c1eb9d h1:qUrYOinhdAUL0xxhA4gPqogPBaS9nIq2l2kTb6pmeB0=
 k8s.io/gengo/v2 v2.0.0-20250820003526-c297c0c1eb9d/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kms v0.34.1 h1:iCFOvewDPzWM9fMTfyIPO+4MeuZ0tcZbugxLNSHFG4w=
-k8s.io/kms v0.34.1/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM=
+k8s.io/kms v0.34.2 h1:91rj4MDZLyIT9KxG8J5/CcMH666Z88CF/xJQeuPfJc8=
+k8s.io/kms v0.34.2/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM=
 k8s.io/kube-aggregator v0.34.1 h1:WNLV0dVNoFKmuyvdWLd92iDSyD/TSTjqwaPj0U9XAEU=
 k8s.io/kube-aggregator v0.34.1/go.mod h1:RU8j+5ERfp0h+gIvWtxRPfsa5nK7rboDm8RST8BJfYQ=
 k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
 k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
-k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI=
-k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A=
-k8s.io/metrics v0.34.1 h1:374Rexmp1xxgRt64Bi0TsjAM8cA/Y8skwCoPdjtIslE=
-k8s.io/metrics v0.34.1/go.mod h1:Drf5kPfk2NJrlpcNdSiAAHn/7Y9KqxpRNagByM7Ei80=
+k8s.io/kubectl v0.34.2 h1:+fWGrVlDONMUmmQLDaGkQ9i91oszjjRAa94cr37hzqA=
+k8s.io/kubectl v0.34.2/go.mod h1:X2KTOdtZZNrTWmUD4oHApJ836pevSl+zvC5sI6oO2YQ=
+k8s.io/metrics v0.34.2 h1:zao91FNDVPRGIiHLO2vqqe21zZVPien1goyzn0hsz90=
+k8s.io/metrics v0.34.2/go.mod h1:Ydulln+8uZZctUM8yrUQX4rfq/Ay6UzsuXf24QJ37Vc=
 k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
 k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0=
diff --git a/hack/internal/tools/go.mod b/hack/internal/tools/go.mod
index ae68c0133..5297c4443 100644
--- a/hack/internal/tools/go.mod
+++ b/hack/internal/tools/go.mod
@@ -34,7 +34,7 @@ require (
 	gopkg.in/yaml.v3 v3.0.1
 	gotest.tools/gotestsum v1.13.0
 	helm.sh/helm/v4 v4.0.0
-	k8s.io/code-generator v0.34.1
+	k8s.io/code-generator v0.34.2
 	sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250407161039-6ad5c1dd4418
 	sigs.k8s.io/controller-tools v0.19.0
 	sigs.k8s.io/kind v0.30.0
@@ -500,15 +500,15 @@ require (
 	helm.sh/helm/v3 v3.19.0 // indirect
 	honnef.co/go/tools v0.6.1 // indirect
 	howett.net/plist v1.0.1 // indirect
-	k8s.io/api v0.34.1 // indirect
-	k8s.io/apiextensions-apiserver v0.34.1 // indirect
-	k8s.io/apimachinery v0.34.1 // indirect
-	k8s.io/apiserver v0.34.1 // indirect
-	k8s.io/cli-runtime v0.34.1 // indirect
-	k8s.io/client-go v0.34.1 // indirect
+	k8s.io/api v0.34.2 // indirect
+	k8s.io/apiextensions-apiserver v0.34.2 // indirect
+	k8s.io/apimachinery v0.34.2 // indirect
+	k8s.io/apiserver v0.34.2 // indirect
+	k8s.io/cli-runtime v0.34.2 // indirect
+	k8s.io/client-go v0.34.2 // indirect
 	k8s.io/cloud-provider v0.34.1 // indirect
 	k8s.io/cluster-bootstrap v0.34.1 // indirect
-	k8s.io/component-base v0.34.1 // indirect
+	k8s.io/component-base v0.34.2 // indirect
 	k8s.io/controller-manager v0.34.1 // indirect
 	k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect
 	k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect
@@ -517,9 +517,9 @@ require (
 	k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
 	k8s.io/kube-proxy v0.34.1 // indirect
 	k8s.io/kube-scheduler v0.34.1 // indirect
-	k8s.io/kubectl v0.34.1 // indirect
+	k8s.io/kubectl v0.34.2 // indirect
 	k8s.io/kubelet v0.34.1 // indirect
-	k8s.io/metrics v0.34.1 // indirect
+	k8s.io/metrics v0.34.2 // indirect
 	k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
 	mvdan.cc/gofumpt v0.9.2 // indirect
 	mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
diff --git a/hack/internal/tools/go.sum b/hack/internal/tools/go.sum
index 3407cbf04..aaa3e6e4a 100644
--- a/hack/internal/tools/go.sum
+++ b/hack/internal/tools/go.sum
@@ -1718,26 +1718,26 @@ honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=
 honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
 howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
 howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
-k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
-k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
-k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI=
-k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
-k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
-k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
-k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA=
-k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0=
-k8s.io/cli-runtime v0.34.1 h1:btlgAgTrYd4sk8vJTRG6zVtqBKt9ZMDeQZo2PIzbL7M=
-k8s.io/cli-runtime v0.34.1/go.mod h1:aVA65c+f0MZiMUPbseU/M9l1Wo2byeaGwUuQEQVVveE=
-k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
-k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
+k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY=
+k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw=
+k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo=
+k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE=
+k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
+k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
+k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE=
+k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI=
+k8s.io/cli-runtime v0.34.2 h1:cct1GEuWc3IyVT8MSCoIWzRGw9HJ/C5rgP32H60H6aE=
+k8s.io/cli-runtime v0.34.2/go.mod h1:X13tsrYexYUCIq8MarCBy8lrm0k0weFPTpcaNo7lms4=
+k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M=
+k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE=
 k8s.io/cloud-provider v0.34.1 h1:FS+4C1vq9pIngd/5LR5Jha1sEbn+fo0HJitgZmUyBNc=
 k8s.io/cloud-provider v0.34.1/go.mod h1:ghyQYfQIWZAXKNS+TEgEiQ8wPuhzIVt3wFO6rKqS/rQ=
 k8s.io/cluster-bootstrap v0.34.1 h1:lyCwJKoeYzGI93vk5Sn/Gz2rzfTRXkRuZYOk2rUsHfA=
 k8s.io/cluster-bootstrap v0.34.1/go.mod h1:9EJfkp7Fu4YBU0F6ysvrI5TndWLo8zufmDSjIWBNd94=
-k8s.io/code-generator v0.34.1 h1:WpphT26E+j7tEgIUfFr5WfbJrktCGzB3JoJH9149xYc=
-k8s.io/code-generator v0.34.1/go.mod h1:DeWjekbDnJWRwpw3s0Jat87c+e0TgkxoR4ar608yqvg=
-k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A=
-k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0=
+k8s.io/code-generator v0.34.2 h1:9bG6jTxmsU3HXE5BNYJTC8AZ1D6hVVfkm8yYSkdkGY0=
+k8s.io/code-generator v0.34.2/go.mod h1:dnDDEd6S/z4uZ+PG1aE58ySCi/lR4+qT3a4DddE4/2I=
+k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ=
+k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM=
 k8s.io/controller-manager v0.34.1 h1:c9Cmun/zF740kmdRQWPGga+4MglT5SlrwsCXDS/KtJI=
 k8s.io/controller-manager v0.34.1/go.mod h1:fGiJDhi3OSzSAB4f40ZkJLAqMQSag9RM+7m5BRhBO3Q=
 k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08=
@@ -1755,12 +1755,12 @@ k8s.io/kube-proxy v0.34.1 h1:cIriNCJY5XmRhXCCyQiazyqi47lbwcBQf0H76fVOpkw=
 k8s.io/kube-proxy v0.34.1/go.mod h1:syed9c5+gUVFMo6p24SnlTHzsp+BMd4ACcTw2dbArw0=
 k8s.io/kube-scheduler v0.34.1 h1:S5td6VZwC3lCqERXclerDXhJ26zYc6JroY0s03+PqJ8=
 k8s.io/kube-scheduler v0.34.1/go.mod h1:UiOkod/w+HKoGut9mz9ie4s4KcI82vmLFdq1iIgsmRs=
-k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI=
-k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A=
+k8s.io/kubectl v0.34.2 h1:+fWGrVlDONMUmmQLDaGkQ9i91oszjjRAa94cr37hzqA=
+k8s.io/kubectl v0.34.2/go.mod h1:X2KTOdtZZNrTWmUD4oHApJ836pevSl+zvC5sI6oO2YQ=
 k8s.io/kubelet v0.34.1 h1:doAaTA9/Yfzbdq/u/LveZeONp96CwX9giW6b+oHn4m4=
 k8s.io/kubelet v0.34.1/go.mod h1:PtV3Ese8iOM19gSooFoQT9iyRisbmJdAPuDImuccbbA=
-k8s.io/metrics v0.34.1 h1:374Rexmp1xxgRt64Bi0TsjAM8cA/Y8skwCoPdjtIslE=
-k8s.io/metrics v0.34.1/go.mod h1:Drf5kPfk2NJrlpcNdSiAAHn/7Y9KqxpRNagByM7Ei80=
+k8s.io/metrics v0.34.2 h1:zao91FNDVPRGIiHLO2vqqe21zZVPien1goyzn0hsz90=
+k8s.io/metrics v0.34.2/go.mod h1:Ydulln+8uZZctUM8yrUQX4rfq/Ay6UzsuXf24QJ37Vc=
 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4=
diff --git a/pkg/cache/queue/cluster_queue.go b/pkg/cache/queue/cluster_queue.go
index 88accd4ff..09477274c 100644
--- a/pkg/cache/queue/cluster_queue.go
+++ b/pkg/cache/queue/cluster_queue.go
@@ -89,7 +89,7 @@ type ClusterQueue struct {
 	active            bool
 
 	// inadmissibleWorkloads are workloads that have been tried at least once and couldn't be admitted.
-	inadmissibleWorkloads map[workload.Reference]*workload.Info
+	inadmissibleWorkloads inadmissibleWorkloads
 
 	// popCycle identifies the last call to Pop. It's incremented when calling Pop.
 	// popCycle and queueInadmissibleCycle are used to track when there is a requeuing
@@ -142,7 +142,7 @@ func newClusterQueueImpl(ctx context.Context, client client.Client, wo workload.
 	lessFunc := queueOrderingFunc(ctx, client, wo, fsResWeights, enableAdmissionFs, afsEntryPenalties, &sw)
 	return &ClusterQueue{
 		heap:                      *heap.New(workloadKey, lessFunc),
-		inadmissibleWorkloads:     make(map[workload.Reference]*workload.Info),
+		inadmissibleWorkloads:     make(inadmissibleWorkloads),
 		queueInadmissibleCycle:    -1,
 		lessFunc:                  lessFunc,
 		rwm:                       sync.RWMutex{},
@@ -190,7 +190,7 @@ func (c *ClusterQueue) PushOrUpdate(wInfo *workload.Info) {
 	defer c.rwm.Unlock()
 	key := workload.Key(wInfo.Obj)
 	c.forgetInflightByKey(key)
-	if oldInfo := c.inadmissibleWorkload(key); oldInfo != nil {
+	if oldInfo := c.inadmissibleWorkloads.get(key); oldInfo != nil {
 		// update in place if the workload was inadmissible and didn't change
 		// to potentially become admissible, unless the Eviction status changed
 		// which can affect the workloads order in the queue.
@@ -200,14 +200,14 @@ func (c *ClusterQueue) PushOrUpdate(wInfo *workload.Info) {
 				apimeta.FindStatusCondition(wInfo.Obj.Status.Conditions, kueue.WorkloadEvicted)) &&
 			equality.Semantic.DeepEqual(apimeta.FindStatusCondition(oldInfo.Obj.Status.Conditions, kueue.WorkloadRequeued),
 				apimeta.FindStatusCondition(wInfo.Obj.Status.Conditions, kueue.WorkloadRequeued)) {
-			c.inadmissibleWorkloads[key] = wInfo
+			c.inadmissibleWorkloads.insert(key, wInfo)
 			return
 		}
 		// otherwise move or update in place in the queue.
-		delete(c.inadmissibleWorkloads, key)
+		c.inadmissibleWorkloads.delete(key)
 	}
 	if c.heap.GetByKey(key) == nil && !c.backoffWaitingTimeExpired(wInfo) {
-		c.inadmissibleWorkloads[key] = wInfo
+		c.inadmissibleWorkloads.insert(key, wInfo)
 		return
 	}
 	c.heap.PushOrUpdate(wInfo)
@@ -248,7 +248,7 @@ func (c *ClusterQueue) Delete(log logr.Logger, w *kueue.Workload) {
 // delete removes the workload from ClusterQueue without lock.
 func (c *ClusterQueue) delete(log logr.Logger, w *kueue.Workload) {
 	key := workload.Key(w)
-	delete(c.inadmissibleWorkloads, key)
+	c.inadmissibleWorkloads.delete(key)
 	c.heap.Delete(key)
 	c.forgetInflightByKey(key)
 	if c.sw.matches(key) {
@@ -266,8 +266,8 @@ func (c *ClusterQueue) DeleteFromLocalQueue(log logr.Logger, q *LocalQueue) {
 	defer c.rwm.Unlock()
 	for _, w := range q.items {
 		key := workload.Key(w.Obj)
-		if c.inadmissibleWorkload(key) != nil {
-			delete(c.inadmissibleWorkloads, key)
+		if c.inadmissibleWorkloads.get(key) != nil {
+			c.inadmissibleWorkloads.delete(key)
 		}
 	}
 	for _, w := range q.items {
@@ -275,12 +275,6 @@ func (c *ClusterQueue) DeleteFromLocalQueue(log logr.Logger, q *LocalQueue) {
 	}
 }
 
-// inadmissibleWorkload retrieves a workload from inadmissibleWorkloads.
-// Returns the workload if it exists and is non-nil, otherwise returns nil.
-func (c *ClusterQueue) inadmissibleWorkload(key workload.Reference) *workload.Info {
-	return c.inadmissibleWorkloads[key]
-}
-
 // requeueIfNotPresent inserts a workload that cannot be admitted into
 // ClusterQueue, unless it is already in the queue. If immediate is true
 // or if there was a call to QueueInadmissibleWorkloads after a call to Pop,
@@ -292,14 +286,14 @@ func (c *ClusterQueue) requeueIfNotPresent(wInfo *workload.Info, immediate bool)
 	key := workload.Key(wInfo.Obj)
 	c.forgetInflightByKey(key)
 
-	inadmissibleWl := c.inadmissibleWorkload(key)
+	inadmissibleWl := c.inadmissibleWorkloads.get(key)
 
 	if c.backoffWaitingTimeExpired(wInfo) &&
 		(immediate || c.queueInadmissibleCycle >= c.popCycle || wInfo.LastAssignment.PendingFlavors()) {
 		// If the workload was inadmissible, move it back into the queue.
 		if inadmissibleWl != nil {
 			wInfo = inadmissibleWl
-			delete(c.inadmissibleWorkloads, key)
+			c.inadmissibleWorkloads.delete(key)
 		}
 		return c.heap.PushIfNotPresent(wInfo)
 	}
@@ -312,7 +306,7 @@ func (c *ClusterQueue) requeueIfNotPresent(wInfo *workload.Info, immediate bool)
 		return false
 	}
 
-	c.inadmissibleWorkloads[key] = wInfo
+	c.inadmissibleWorkloads.insert(key, wInfo)
 
 	return true
 }
@@ -329,13 +323,13 @@ func (c *ClusterQueue) QueueInadmissibleWorkloads(ctx context.Context, client cl
 	c.rwm.Lock()
 	defer c.rwm.Unlock()
 	c.queueInadmissibleCycle = c.popCycle
-	if len(c.inadmissibleWorkloads) == 0 {
+	if c.inadmissibleWorkloads.empty() {
 		return false
 	}
 
 	inadmissibleWorkloads := make(map[workload.Reference]*workload.Info)
 	moved := false
-	for key, wInfo := range c.inadmissibleWorkloads {
+	c.inadmissibleWorkloads.forEach(func(key workload.Reference, wInfo *workload.Info) bool {
 		ns := corev1.Namespace{}
 		err := client.Get(ctx, types.NamespacedName{Name: wInfo.Obj.Namespace}, &ns)
 		if err != nil || !c.namespaceSelector.Matches(labels.Set(ns.Labels)) || !c.backoffWaitingTimeExpired(wInfo) {
@@ -343,9 +337,10 @@ func (c *ClusterQueue) QueueInadmissibleWorkloads(ctx context.Context, client cl
 		} else {
 			moved = c.heap.PushIfNotPresent(wInfo) || moved
 		}
-	}
+		return true
+	})
 
-	c.inadmissibleWorkloads = inadmissibleWorkloads
+	c.inadmissibleWorkloads.replaceAll(inadmissibleWorkloads)
 	return moved
 }
 
@@ -376,7 +371,7 @@ func (c *ClusterQueue) pendingActive() int {
 // workloads that were already tried and are waiting for cluster conditions
 // to change to potentially become admissible.
 func (c *ClusterQueue) pendingInadmissible() int {
-	return len(c.inadmissibleWorkloads)
+	return c.inadmissibleWorkloads.len()
 }
 
 // PendingInLocalQueue returns the number of active and inadmissible pending workloads in LocalQueue.
@@ -405,12 +400,13 @@ func (c *ClusterQueue) pendingActiveInLocalQueue(lqRef utilqueue.LocalQueueRefer
 // workloads that were already tried and are waiting for cluster conditions
 // to change to potentially become admissible.
 func (c *ClusterQueue) pendingInadmissibleInLocalQueue(lqRef utilqueue.LocalQueueReference) (inadmissible int) {
-	for _, wl := range c.inadmissibleWorkloads {
+	c.inadmissibleWorkloads.forEach(func(_ workload.Reference, wl *workload.Info) bool {
 		wlLqKey := utilqueue.KeyFromWorkload(wl.Obj)
 		if wlLqKey == lqRef {
 			inadmissible++
 		}
-	}
+		return true
+	})
 	return
 }
 
diff --git a/pkg/cache/queue/inadmissible_workloads.go b/pkg/cache/queue/inadmissible_workloads.go
new file mode 100644
index 000000000..453dc5612
--- /dev/null
+++ b/pkg/cache/queue/inadmissible_workloads.go
@@ -0,0 +1,66 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package queue
+
+import (
+	"sigs.k8s.io/kueue/pkg/workload"
+)
+
+// inadmissibleWorkloads is a thin wrapper around a map to encapsulate
+// operations on inadmissible workloads and prevent direct map access.
+type inadmissibleWorkloads map[workload.Reference]*workload.Info
+
+// get retrieves a workload from the inadmissible workloads map.
+// Returns the workload if it exists, otherwise returns nil.
+func (iw inadmissibleWorkloads) get(key workload.Reference) *workload.Info {
+	return iw[key]
+}
+
+// delete removes a workload from the inadmissible workloads map.
+func (iw inadmissibleWorkloads) delete(key workload.Reference) {
+	delete(iw, key)
+}
+
+// insert adds a workload to the inadmissible workloads map.
+func (iw inadmissibleWorkloads) insert(key workload.Reference, wInfo *workload.Info) {
+	iw[key] = wInfo
+}
+
+// len returns the number of inadmissible workloads.
+func (iw inadmissibleWorkloads) len() int {
+	return len(iw)
+}
+
+// empty returns true if there are no inadmissible workloads.
+func (iw inadmissibleWorkloads) empty() bool {
+	return len(iw) == 0
+}
+
+// forEach iterates over all inadmissible workloads and calls the provided function.
+// The iteration can be stopped early by returning false from the function.
+func (iw inadmissibleWorkloads) forEach(f func(key workload.Reference, wInfo *workload.Info) bool) {
+	for key, wInfo := range iw {
+		if !f(key, wInfo) {
+			return
+		}
+	}
+}
+
+// replaceAll replaces all inadmissible workloads with the provided map.
+func (iw *inadmissibleWorkloads) replaceAll(newMap map[workload.Reference]*workload.Info) {
+	*iw = newMap
+}
diff --git a/pkg/controller/admissionchecks/multikueue/multikueuecluster.go b/pkg/controller/admissionchecks/multikueue/multikueuecluster.go
index 7ce091cd1..966f00f1a 100644
--- a/pkg/controller/admissionchecks/multikueue/multikueuecluster.go
+++ b/pkg/controller/admissionchecks/multikueue/multikueuecluster.go
@@ -423,10 +423,7 @@ func (c *clustersReconciler) Reconcile(ctx context.Context, req reconcile.Reques
 		return reconcile.Result{}, nil //nolint:nilerr // nil is intentional, as either the cluster is deleted, or not found
 	}
 
-	clientConfig, retry, reason, err := c.loadClientConfig(ctx, cluster)
-	if retry {
-		return reconcile.Result{}, err
-	}
+	clientConfig, reason, err := c.loadClientConfig(ctx, cluster)
 	if err != nil {
 		log.Error(err, "loading client config failed")
 		c.stopAndRemoveCluster(req.Name)
@@ -448,39 +445,39 @@ func (c *clustersReconciler) Reconcile(ctx context.Context, req reconcile.Reques
 	return reconcile.Result{}, client.IgnoreNotFound(c.updateStatus(ctx, cluster, true, "Active", "Connected"))
 }
 
-func (c *clustersReconciler) loadClientConfig(ctx context.Context, cluster *kueue.MultiKueueCluster) (*clientConfig, bool, string, error) {
+func (c *clustersReconciler) loadClientConfig(ctx context.Context, cluster *kueue.MultiKueueCluster) (*clientConfig, string, error) {
 	log := ctrl.LoggerFrom(ctx)
 	if cluster.Spec.ClusterSource.ClusterProfileRef != nil {
 		if !features.Enabled(features.MultiKueueClusterProfile) {
-			return nil, false, "MultiKueueClusterProfileFeatureDisabled", errors.New("MultiKueueClusterProfile feature gate is disabled")
+			return nil, "MultiKueueClusterProfileFeatureDisabled", errors.New("MultiKueueClusterProfile feature gate is disabled")
 		}
-		restConfig, retry, err := c.getRestConfigFromClusterProfile(ctx, cluster.Spec.ClusterSource.ClusterProfileRef)
+		restConfig, err := c.getRestConfigFromClusterProfile(ctx, cluster.Spec.ClusterSource.ClusterProfileRef)
 		if err != nil {
-			return nil, retry, "BadClusterProfile", err
+			return nil, "BadClusterProfile", err
 		}
 		opts := validateRestConfigOptions{
 			// ExecProvider is allowed for ClusterProfile credentials plugins.
 			allowExecProvider: true,
 		}
 		if err := validateRestConfig(restConfig, opts); err != nil {
-			return nil, false, "BadRestConfig", err
+			return nil, "BadRestConfig", err
 		}
-		return &clientConfig{RestConfig: restConfig}, false, "", nil
+		return &clientConfig{RestConfig: restConfig}, "", nil
 	}
 
-	kubeConfig, retry, err := c.getKubeConfig(ctx, cluster.Spec.ClusterSource.KubeConfig)
+	kubeConfig, err := c.getKubeConfig(ctx, cluster.Spec.ClusterSource.KubeConfig)
 	if err != nil {
-		return nil, retry, "BadKubeConfig", err
+		return nil, "BadKubeConfig", err
 	}
 
 	if features.Enabled(features.MultiKueueAllowInsecureKubeconfigs) {
 		log.V(3).Info("Feature MultiKueueAllowInsecureKubeconfigs is enabled, skipping kubeconfig validation")
-		return &clientConfig{Kubeconfig: kubeConfig}, false, "", nil
+		return &clientConfig{Kubeconfig: kubeConfig}, "", nil
 	}
 	if err := validateKubeconfig(kubeConfig); err != nil {
-		return nil, false, "InsecureKubeConfig", err
+		return nil, "InsecureKubeConfig", err
 	}
-	return &clientConfig{Kubeconfig: kubeConfig}, false, "", nil
+	return &clientConfig{Kubeconfig: kubeConfig}, "", nil
 }
 
 // validateKubeconfig checks that the provided kubeconfig content is safe to use
@@ -569,9 +566,9 @@ func isValidHostname(server string) bool {
 	return len(errs) == 0
 }
 
-func (c *clustersReconciler) getKubeConfig(ctx context.Context, ref *kueue.KubeConfig) ([]byte, bool, error) {
+func (c *clustersReconciler) getKubeConfig(ctx context.Context, ref *kueue.KubeConfig) ([]byte, error) {
 	if ref == nil {
-		return nil, false, errors.New("kubeconfig reference is nil")
+		return nil, errors.New("kubeconfig reference is nil")
 	}
 
 	if ref.LocationType == kueue.SecretLocationType {
@@ -581,21 +578,16 @@ func (c *clustersReconciler) getKubeConfig(ctx context.Context, ref *kueue.KubeC
 	return c.getKubeConfigFromPath(ref.Location)
 }
 
-func (c *clustersReconciler) getRestConfigFromClusterProfile(ctx context.Context, profileRef *kueue.ClusterProfileReference) (*rest.Config, bool, error) {
+func (c *clustersReconciler) getRestConfigFromClusterProfile(ctx context.Context, profileRef *kueue.ClusterProfileReference) (*rest.Config, error) {
 	cp := &inventoryv1alpha1.ClusterProfile{}
 	if err := c.localClient.Get(ctx, types.NamespacedName{Name: profileRef.Name, Namespace: c.configNamespace}, cp); err != nil {
-		return nil, !apierrors.IsNotFound(err), err
-	}
-
-	restConfig, err := c.clusterProfileCreds.BuildConfigFromCP(cp)
-	if err != nil {
-		return nil, false, err
+		return nil, err
 	}
 
-	return restConfig, false, nil
+	return c.clusterProfileCreds.BuildConfigFromCP(cp)
 }
 
-func (c *clustersReconciler) getKubeConfigFromSecret(ctx context.Context, secretName string) ([]byte, bool, error) {
+func (c *clustersReconciler) getKubeConfigFromSecret(ctx context.Context, secretName string) ([]byte, error) {
 	sec := corev1.Secret{}
 	secretObjKey := types.NamespacedName{
 		Namespace: c.configNamespace,
@@ -603,20 +595,19 @@ func (c *clustersReconciler) getKubeConfigFromSecret(ctx context.Context, secret
 	}
 	err := c.localClient.Get(ctx, secretObjKey, &sec)
 	if err != nil {
-		return nil, !apierrors.IsNotFound(err), err
+		return nil, err
 	}
 
 	kconfigBytes, found := sec.Data[kueue.MultiKueueConfigSecretKey]
 	if !found {
-		return nil, false, fmt.Errorf("key %q not found in secret %q", kueue.MultiKueueConfigSecretKey, secretName)
+		return nil, fmt.Errorf("key %q not found in secret %q", kueue.MultiKueueConfigSecretKey, secretName)
 	}
 
-	return kconfigBytes, false, nil
+	return kconfigBytes, nil
 }
 
-func (c *clustersReconciler) getKubeConfigFromPath(path string) ([]byte, bool, error) {
-	content, err := os.ReadFile(path)
-	return content, false, err
+func (c *clustersReconciler) getKubeConfigFromPath(path string) ([]byte, error) {
+	return os.ReadFile(path)
 }
 
 func (c *clustersReconciler) updateStatus(ctx context.Context, cluster *kueue.MultiKueueCluster, active bool, reason, message string) error {
diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go
index 5d2054155..79a748b74 100644
--- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go
+++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go
@@ -77,6 +77,9 @@ func (ll *LeaseLock) Update(ctx context.Context, ler LeaderElectionRecord) error
 	ll.lease.Spec = LeaderElectionRecordToLeaseSpec(&ler)
 
 	if ll.Labels != nil {
+		if ll.lease.Labels == nil {
+			ll.lease.Labels = map[string]string{}
+		}
 		// Only overwrite the labels that are specifically set
 		for k, v := range ll.Labels {
 			ll.lease.Labels[k] = v
diff --git a/vendor/k8s.io/client-go/util/cert/cert.go b/vendor/k8s.io/client-go/util/cert/cert.go
index 122046126..48c78b595 100644
--- a/vendor/k8s.io/client-go/util/cert/cert.go
+++ b/vendor/k8s.io/client-go/util/cert/cert.go
@@ -75,13 +75,15 @@ func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, erro
 			CommonName:   cfg.CommonName,
 			Organization: cfg.Organization,
 		},
-		DNSNames:              []string{cfg.CommonName},
 		NotBefore:             notBefore,
 		NotAfter:              now.Add(duration365d * 10).UTC(),
 		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
 		BasicConstraintsValid: true,
 		IsCA:                  true,
 	}
+	if len(cfg.CommonName) > 0 {
+		tmpl.DNSNames = []string{cfg.CommonName}
+	}
 
 	certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key)
 	if err != nil {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 9cd274647..0a2cc6650 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -732,7 +732,7 @@ gopkg.in/natefinch/lumberjack.v2
 # gopkg.in/yaml.v3 v3.0.1
 ## explicit
 gopkg.in/yaml.v3
-# k8s.io/api v0.34.1
+# k8s.io/api v0.34.2
 ## explicit; go 1.24.0
 k8s.io/api/admission/v1
 k8s.io/api/admission/v1beta1
@@ -794,7 +794,7 @@ k8s.io/api/storage/v1
 k8s.io/api/storage/v1alpha1
 k8s.io/api/storage/v1beta1
 k8s.io/api/storagemigration/v1alpha1
-# k8s.io/apiextensions-apiserver v0.34.1
+# k8s.io/apiextensions-apiserver v0.34.2
 ## explicit; go 1.24.0
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
@@ -805,7 +805,7 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset
 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme
 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1
 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1
-# k8s.io/apimachinery v0.34.1
+# k8s.io/apimachinery v0.34.2
 ## explicit; go 1.24.0
 k8s.io/apimachinery/pkg/api/equality
 k8s.io/apimachinery/pkg/api/errors
@@ -881,7 +881,7 @@ k8s.io/apimachinery/pkg/watch
 k8s.io/apimachinery/third_party/forked/golang/json
 k8s.io/apimachinery/third_party/forked/golang/netutil
 k8s.io/apimachinery/third_party/forked/golang/reflect
-# k8s.io/apiserver v0.34.1
+# k8s.io/apiserver v0.34.2
 ## explicit; go 1.24.0
 k8s.io/apiserver/pkg/admission
 k8s.io/apiserver/pkg/admission/configuration
@@ -1053,13 +1053,13 @@ k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics
 # k8s.io/autoscaler/cluster-autoscaler/apis v0.0.0-20240830133931-adfbe7e45277
 ## explicit; go 1.22.0
 k8s.io/autoscaler/cluster-autoscaler/apis/provisioningrequest/autoscaling.x-k8s.io/v1
-# k8s.io/cli-runtime v0.34.1
+# k8s.io/cli-runtime v0.34.2
 ## explicit; go 1.24.0
 k8s.io/cli-runtime/pkg/genericclioptions
 k8s.io/cli-runtime/pkg/genericiooptions
 k8s.io/cli-runtime/pkg/printers
 k8s.io/cli-runtime/pkg/resource
-# k8s.io/client-go v0.34.1
+# k8s.io/client-go v0.34.2
 ## explicit; go 1.24.0
 k8s.io/client-go/applyconfigurations
 k8s.io/client-go/applyconfigurations/admissionregistration/v1
@@ -1421,7 +1421,7 @@ k8s.io/client-go/util/jsonpath
 k8s.io/client-go/util/keyutil
 k8s.io/client-go/util/retry
 k8s.io/client-go/util/workqueue
-# k8s.io/code-generator v0.34.1
+# k8s.io/code-generator v0.34.2
 ## explicit; go 1.24.0
 k8s.io/code-generator
 k8s.io/code-generator/cmd/applyconfiguration-gen
@@ -1457,7 +1457,7 @@ k8s.io/code-generator/cmd/register-gen/generators
 k8s.io/code-generator/pkg/namer
 k8s.io/code-generator/pkg/util
 k8s.io/code-generator/third_party/forked/golang/reflect
-# k8s.io/component-base v0.34.1
+# k8s.io/component-base v0.34.2
 ## explicit; go 1.24.0
 k8s.io/component-base/cli/flag
 k8s.io/component-base/compatibility
@@ -1486,7 +1486,7 @@ k8s.io/component-base/zpages/features
 k8s.io/component-base/zpages/flagz
 k8s.io/component-base/zpages/httputil
 k8s.io/component-base/zpages/statusz
-# k8s.io/component-helpers v0.34.1
+# k8s.io/component-helpers v0.34.2
 ## explicit; go 1.24.0
 k8s.io/component-helpers/resource
 k8s.io/component-helpers/scheduling/corev1
@@ -1510,7 +1510,7 @@ k8s.io/klog/v2/internal/severity
 k8s.io/klog/v2/internal/sloghandler
 k8s.io/klog/v2/internal/verbosity
 k8s.io/klog/v2/textlogger
-# k8s.io/kms v0.34.1
+# k8s.io/kms v0.34.2
 ## explicit; go 1.24.0
 k8s.io/kms/apis/v1beta1
 k8s.io/kms/apis/v2
@@ -1544,7 +1544,7 @@ k8s.io/kube-openapi/pkg/validation/errors
 k8s.io/kube-openapi/pkg/validation/spec
 k8s.io/kube-openapi/pkg/validation/strfmt
 k8s.io/kube-openapi/pkg/validation/strfmt/bson
-# k8s.io/kubectl v0.34.1
+# k8s.io/kubectl v0.34.2
 ## explicit; go 1.24.0
 k8s.io/kubectl/pkg/cmd/get
 k8s.io/kubectl/pkg/cmd/util
@@ -1556,7 +1556,7 @@ k8s.io/kubectl/pkg/util/openapi
 k8s.io/kubectl/pkg/util/templates
 k8s.io/kubectl/pkg/util/term
 k8s.io/kubectl/pkg/validation
-# k8s.io/metrics v0.34.1
+# k8s.io/metrics v0.34.2
 ## explicit; go 1.24.0
 k8s.io/metrics/pkg/apis/metrics
 k8s.io/metrics/pkg/apis/metrics/install



Test patch:
diff --git a/pkg/cache/queue/cluster_queue_test.go b/pkg/cache/queue/cluster_queue_test.go
index f8770ea05..2c659b19b 100644
--- a/pkg/cache/queue/cluster_queue_test.go
+++ b/pkg/cache/queue/cluster_queue_test.go
@@ -70,7 +70,7 @@ func Test_PushOrUpdate(t *testing.T) {
 	cases := map[string]struct {
 		workload                  *utiltestingapi.WorkloadWrapper
 		wantWorkload              *workload.Info
-		wantInAdmissibleWorkloads map[workload.Reference]*workload.Info
+		wantInAdmissibleWorkloads inadmissibleWorkloads
 	}{
 		"workload doesn't have re-queue state": {
 			workload:     wlBase.Clone(),
@@ -88,7 +88,7 @@ func Test_PushOrUpdate(t *testing.T) {
 					Type:   kueue.WorkloadRequeued,
 					Status: metav1.ConditionFalse,
 				}),
-			wantInAdmissibleWorkloads: map[workload.Reference]*workload.Info{
+			wantInAdmissibleWorkloads: inadmissibleWorkloads{
 				"default/workload-1": workload.NewInfo(wlBase.Clone().
 					ResourceVersion("1").
 					RequeueState(ptr.To[int32](10), ptr.To(metav1.NewTime(minuteLater))).
@@ -115,7 +115,7 @@ func Test_PushOrUpdate(t *testing.T) {
 					Type:   kueue.WorkloadRequeued,
 					Status: metav1.ConditionFalse,
 				}),
-			wantInAdmissibleWorkloads: map[workload.Reference]*workload.Info{
+			wantInAdmissibleWorkloads: inadmissibleWorkloads{
 				"default/workload-1": workload.NewInfo(wlBase.Clone().
 					ResourceVersion("1").
 					Condition(metav1.Condition{
diff --git a/pkg/cache/queue/inadmissible_workloads_test.go b/pkg/cache/queue/inadmissible_workloads_test.go
new file mode 100644
index 000000000..f86f882eb
--- /dev/null
+++ b/pkg/cache/queue/inadmissible_workloads_test.go
@@ -0,0 +1,418 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package queue
+
+import (
+	"maps"
+	"testing"
+
+	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
+	"sigs.k8s.io/kueue/pkg/workload"
+)
+
+func TestInadmissibleWorkloads_Get(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	wl2 := workload.NewInfo(utiltestingapi.MakeWorkload("wl2", "ns2").Obj())
+	key1 := workload.Key(wl1.Obj)
+	key2 := workload.Key(wl2.Obj)
+
+	testcases := []struct {
+		name         string
+		initial      map[workload.Reference]*workload.Info
+		key          workload.Reference
+		wantWorkload *workload.Info
+	}{
+		{
+			name:         "returns nil for non-existent workload",
+			initial:      nil,
+			key:          key1,
+			wantWorkload: nil,
+		},
+		{
+			name: "returns workload when exists",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			key:          key1,
+			wantWorkload: wl1,
+		},
+		{
+			name: "returns nil for different key",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			key:          key2,
+			wantWorkload: nil,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			got := iw.get(tc.key)
+			if got != tc.wantWorkload {
+				t.Errorf("get() = %v, want %v", got, tc.wantWorkload)
+			}
+		})
+	}
+}
+
+func TestInadmissibleWorkloads_Insert(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	wl2 := workload.NewInfo(utiltestingapi.MakeWorkload("wl2", "ns2").Obj())
+	key1 := workload.Key(wl1.Obj)
+	key2 := workload.Key(wl2.Obj)
+
+	testcases := []struct {
+		name    string
+		initial map[workload.Reference]*workload.Info
+		key     workload.Reference
+		value   *workload.Info
+		wantLen int
+	}{
+		{
+			name:    "insert into empty map",
+			initial: nil,
+			key:     key1,
+			value:   wl1,
+			wantLen: 1,
+		},
+		{
+			name: "insert new workload",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			key:     key2,
+			value:   wl2,
+			wantLen: 2,
+		},
+		{
+			name: "overwrite existing workload",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			key:     key1,
+			value:   wl2,
+			wantLen: 1,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			iw.insert(tc.key, tc.value)
+
+			if got := iw.len(); got != tc.wantLen {
+				t.Errorf("after insert, len() = %d, want %d", got, tc.wantLen)
+			}
+			if got := iw.get(tc.key); got != tc.value {
+				t.Errorf("after insert, get() = %v, want %v", got, tc.value)
+			}
+		})
+	}
+}
+
+func TestInadmissibleWorkloads_Delete(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	wl2 := workload.NewInfo(utiltestingapi.MakeWorkload("wl2", "ns2").Obj())
+	key1 := workload.Key(wl1.Obj)
+	key2 := workload.Key(wl2.Obj)
+
+	testcases := []struct {
+		name    string
+		initial map[workload.Reference]*workload.Info
+		key     workload.Reference
+		wantLen int
+	}{
+		{
+			name:    "delete from empty map",
+			initial: nil,
+			key:     key1,
+			wantLen: 0,
+		},
+		{
+			name: "delete existing workload",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			key:     key1,
+			wantLen: 0,
+		},
+		{
+			name: "delete non-existent workload",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			key:     key2,
+			wantLen: 1,
+		},
+		{
+			name: "delete one of multiple workloads",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+				key2: wl2,
+			},
+			key:     key1,
+			wantLen: 1,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			iw.delete(tc.key)
+
+			if got := iw.len(); got != tc.wantLen {
+				t.Errorf("after delete, len() = %d, want %d", got, tc.wantLen)
+			}
+			if got := iw.get(tc.key); got != nil {
+				t.Errorf("after delete, get() = %v, want nil", got)
+			}
+		})
+	}
+}
+
+func TestInadmissibleWorkloads_Len(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	wl2 := workload.NewInfo(utiltestingapi.MakeWorkload("wl2", "ns2").Obj())
+	key1 := workload.Key(wl1.Obj)
+	key2 := workload.Key(wl2.Obj)
+
+	testcases := []struct {
+		name    string
+		initial map[workload.Reference]*workload.Info
+		wantLen int
+	}{
+		{
+			name:    "empty map",
+			initial: nil,
+			wantLen: 0,
+		},
+		{
+			name: "single workload",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			wantLen: 1,
+		},
+		{
+			name: "multiple workloads",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+				key2: wl2,
+			},
+			wantLen: 2,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			if got := iw.len(); got != tc.wantLen {
+				t.Errorf("len() = %d, want %d", got, tc.wantLen)
+			}
+		})
+	}
+}
+
+func TestInadmissibleWorkloads_Empty(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	key1 := workload.Key(wl1.Obj)
+
+	testcases := []struct {
+		name      string
+		initial   map[workload.Reference]*workload.Info
+		wantEmpty bool
+	}{
+		{
+			name:      "empty map",
+			initial:   nil,
+			wantEmpty: true,
+		},
+		{
+			name: "non-empty map",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			wantEmpty: false,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			if got := iw.empty(); got != tc.wantEmpty {
+				t.Errorf("empty() = %v, want %v", got, tc.wantEmpty)
+			}
+		})
+	}
+}
+
+func TestInadmissibleWorkloads_ForEach(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	wl2 := workload.NewInfo(utiltestingapi.MakeWorkload("wl2", "ns2").Obj())
+	key1 := workload.Key(wl1.Obj)
+	key2 := workload.Key(wl2.Obj)
+
+	testcases := []struct {
+		name           string
+		initial        map[workload.Reference]*workload.Info
+		stopAfter      int
+		wantVisited    int
+		wantAllVisited bool
+	}{
+		{
+			name:           "iterate over empty map",
+			initial:        nil,
+			stopAfter:      0,
+			wantVisited:    0,
+			wantAllVisited: true,
+		},
+		{
+			name: "iterate over all workloads",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+				key2: wl2,
+			},
+			stopAfter:      2,
+			wantVisited:    2,
+			wantAllVisited: true,
+		},
+		{
+			name: "stop early",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+				key2: wl2,
+			},
+			stopAfter:      1,
+			wantVisited:    1,
+			wantAllVisited: false,
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			visited := 0
+			seen := make(map[workload.Reference]bool)
+			iw.forEach(func(key workload.Reference, wInfo *workload.Info) bool {
+				visited++
+				seen[key] = true
+				return visited < tc.stopAfter
+			})
+
+			if visited != tc.wantVisited {
+				t.Errorf("visited %d workloads, want %d", visited, tc.wantVisited)
+			}
+
+			if tc.wantAllVisited {
+				for k := range tc.initial {
+					if !seen[k] {
+						t.Errorf("workload %v was not visited", k)
+					}
+				}
+			}
+		})
+	}
+}
+
+func TestInadmissibleWorkloads_ReplaceAll(t *testing.T) {
+	wl1 := workload.NewInfo(utiltestingapi.MakeWorkload("wl1", "ns1").Obj())
+	wl2 := workload.NewInfo(utiltestingapi.MakeWorkload("wl2", "ns2").Obj())
+	wl3 := workload.NewInfo(utiltestingapi.MakeWorkload("wl3", "ns3").Obj())
+	key1 := workload.Key(wl1.Obj)
+	key2 := workload.Key(wl2.Obj)
+	key3 := workload.Key(wl3.Obj)
+
+	testcases := []struct {
+		name       string
+		initial    map[workload.Reference]*workload.Info
+		newMap     map[workload.Reference]*workload.Info
+		wantLen    int
+		checkKeys  []workload.Reference
+		wantExists []bool
+	}{
+		{
+			name: "replace with empty map",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			newMap:     map[workload.Reference]*workload.Info{},
+			wantLen:    0,
+			checkKeys:  []workload.Reference{key1},
+			wantExists: []bool{false},
+		},
+		{
+			name: "replace with different workloads",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			newMap: map[workload.Reference]*workload.Info{
+				key2: wl2,
+			},
+			wantLen:    1,
+			checkKeys:  []workload.Reference{key1, key2},
+			wantExists: []bool{false, true},
+		},
+		{
+			name: "replace with multiple workloads",
+			initial: map[workload.Reference]*workload.Info{
+				key1: wl1,
+			},
+			newMap: map[workload.Reference]*workload.Info{
+				key2: wl2,
+				key3: wl3,
+			},
+			wantLen:    2,
+			checkKeys:  []workload.Reference{key1, key2, key3},
+			wantExists: []bool{false, true, true},
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			iw := make(inadmissibleWorkloads)
+			maps.Copy(iw, tc.initial)
+
+			iw.replaceAll(tc.newMap)
+
+			if got := iw.len(); got != tc.wantLen {
+				t.Errorf("after replaceAll, len() = %d, want %d", got, tc.wantLen)
+			}
+
+			for i, key := range tc.checkKeys {
+				got := iw.get(key)
+				exists := got != nil
+				if exists != tc.wantExists[i] {
+					t.Errorf("after replaceAll, key %v exists = %v, want %v", key, exists, tc.wantExists[i])
+				}
+			}
+		})
+	}
+}