kubeslice / kubeslice/kubeslice-controller

Bug: validateApplicationNamespaces panics on empty SliceNamespaceSelection entry

Open
#321 0 comments 0 reactions 1 assignee Claimed by @richiesebastian View on GitHub
bug
Dominant language
Go
Stars
73
Forks
48
Avg merge
2d 21h
Merged PRs (30d)
8

Description

### 📜 Description

`validateApplicationNamespaces` in `service/slice_config_webhook_validation.go` panics with an index-out-of-range error when a `SliceNamespaceSelection` entry has both `namespace` and `clusters` empty.

Lines 508–513 guard against only one of the two fields being empty:

- Line 508: rejects `namespace` set + `clusters` empty
- Line 511: rejects `namespace` empty + `clusters` set

But when both are empty (a zero-value `SliceNamespaceSelection{}`), both guards pass. Line 514 calls `CheckDuplicateInArray` on an empty slice, which returns false. Execution then reaches line 517:

```go
// service/slice_config_webhook_validation.go, line 517
if applicationNamespace.Clusters[0] == "*" {
```

This indexes into an empty slice and panics. Since the webhook runs in-process with the controller manager, this crashes the entire controller.

### 👟 Reproduction steps

1. Have an existing Project with a registered cluster:

kubectl get clusters -n kubeslice-my-project

2. Apply a SliceConfig with an empty entry in `applicationNamespaces`:

apiVersion: controller.kubeslice.io/v1alpha1
kind: SliceConfig
metadata:
name: test-slice
namespace: kubeslice-my-project
spec:
sliceSubnet: 10.1.0.0/16
maxClusters: 16
clusters:
- worker-1
namespaceIsolationProfile:
applicationNamespaces:
- {}

3. The validating webhook panics and the controller manager crashes.

### 👍 Expected behavior

The webhook should reject the request with a validation error indicating that both `namespace` and `clusters` are required. The controller should not crash.

### 👎 Actual Behavior

The controller manager panics with:

runtime error: index out of range [0] with length 0

goroutine ... [running]:
github.com/kubeslice/kubeslice-controller/service.validateApplicationNamespaces(...)
service/slice_config_webhook_validation.go:517

The webhook process crashes, taking down all reconciliation cluster-wide until the pod restarts.

### 🐚 Relevant log output

```shell
The panic occurs before any log statement in the function. The only output is the Go runtime
panic trace, visible in the controller manager pod logs:

panic: runtime error: index out of range [0] with length 0

goroutine 123 [running]:
github.com/kubeslice/kubeslice-controller/service.validateApplicationNamespaces(0x...)
/workspace/service/slice_config_webhook_validation.go:517
github.com/kubeslice/kubeslice-controller/service.ValidateSliceConfigCreate(0x...)
/workspace/service/slice_config_webhook_validation.go:38
```

### Version

master branch (latest HEAD as of 2026-05-08). The bug exists in all releases containing the `validateApplicationNamespaces` function. Affected release branches include release-shimla, release-udaipur, and release-varanasi.

### 🖥️ What operating system are you seeing the problem on?

Windows

### ✅ Proposed Solution

Add an explicit rejection for empty entries before the existing guards. Apply at `service/slice_config_webhook_validation.go`, insert before line 508:

Current code (lines 506–517):

for _, applicationNamespace := range sliceConfig.Spec.NamespaceIsolationProfile.ApplicationNamespaces {
/* check duplicate values of clusters */
if len(applicationNamespace.Namespace) > 0 && len(applicationNamespace.Clusters) == 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Clusters"), "clusters")
}
if len(applicationNamespace.Namespace) == 0 && len(applicationNamespace.Clusters) > 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Namespace"), "Namespace")
}
if duplicate, value := util.CheckDuplicateInArray(applicationNamespace.Clusters); duplicate {
return field.Duplicate(field.NewPath("Spec").Child("NamespaceIsolationProfile.ApplicationNamespaces").Child("Clusters"), strings.Join(value, ", "))
}
if applicationNamespace.Clusters[0] == "*" {

Fixed code (lines 506–520):

for _, applicationNamespace := range sliceConfig.Spec.NamespaceIsolationProfile.ApplicationNamespaces {
/* check duplicate values of clusters */
if len(applicationNamespace.Namespace) == 0 && len(applicationNamespace.Clusters) == 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces"), "namespace and clusters are required")
}
if len(applicationNamespace.Namespace) > 0 && len(applicationNamespace.Clusters) == 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Clusters"), "clusters")
}
if len(applicationNamespace.Namespace) == 0 && len(applicationNamespace.Clusters) > 0 {
return field.Required(field.NewPath("Spec").Child("NamespaceIsolationProfile").Child("ApplicationNamespaces").Child("Namespace"), "Namespace")
}
if duplicate, value := util.CheckDuplicateInArray(applicationNamespace.Clusters); duplicate {
return field.Duplicate(field.NewPath("Spec").Child("NamespaceIsolationProfile.ApplicationNamespaces").Child("Clusters"), strings.Join(value, ", "))
}
if applicationNamespace.Clusters[0] == "*" {

The new guard at the top catches the both-empty case before execution can reach line 517. This gives the user a clear validation error instead of crashing the controller.

### 👀 Have you spent some time to check if this issue has been raised before?

- [x] I checked and didn't find any similar issue

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.