π Description
copySpecFromSliceConfigToWorkerSlice in service/worker_slice_config_service.go at lines 687β694 uses copier.Copy to deep-copy the SliceConfig spec into a WorkerSliceConfig. If the copy fails, the function silently returns an empty WorkerSliceConfig{} with a zeroed spec. The caller then overwrites the existing worker slice config with this empty spec and pushes it to the API server.
// service/worker_slice_config_service.go, lines 686-694
func (s *WorkerSliceConfigService) copySpecFromSliceConfigToWorkerSlice(ctx context.Context,
sliceConfig controllerv1alpha1.SliceConfig) workerv1alpha1.WorkerSliceConfig {
slice := workerv1alpha1.WorkerSliceConfig{}
err := copier.Copy(&slice.Spec, &sliceConfig.Spec)
if err != nil {
return workerv1alpha1.WorkerSliceConfig{} // β empty spec, error discarded
}
return slice
}
The caller at lines 165β166 and 282:
// line 165-166
slice := s.copySpecFromSliceConfigToWorkerSlice(ctx, *sliceConfig)
workerSliceConfig.Spec = slice.Spec // overwrites with empty spec if copier failed
// ... fields are set on top of the (possibly empty) spec ...
// line 282
err = util.UpdateResource(ctx, workerSliceConfig) // pushes to API server
If copier.Copy fails, slice.Spec is a zero-valued WorkerSliceConfigSpec. The caller overwrites workerSliceConfig.Spec with this empty struct, losing all existing configuration. Some fields are re-set afterward (Octet, ClusterSubnetCIDR, SliceName at lines 279β281), but critical fields from the SliceConfig spec β such as SliceType, SliceSubnet, SliceIpamType, Clusters, MaxClusters, and the entire SliceGatewayProvider β are zeroed.
π Reproduction steps
-
Create a SliceConfig with a full spec (QoS profile, external gateway config, namespace isolation, etc.)
-
Register clusters and wait for WorkerSliceConfigs to be created and fully reconciled.
-
Trigger a copier.Copy failure. While unlikely in normal operation, this can occur when:
- A dependency update changes struct field types or tags that
copier relies on
- Memory pressure causes allocation failures during the deep copy
- A custom type implements an interface that
copier doesn't handle correctly
-
The reconciler calls copySpecFromSliceConfigToWorkerSlice, which returns an empty WorkerSliceConfig{}.
-
The caller overwrites workerSliceConfig.Spec with the empty spec, then calls util.UpdateResource. The API server receives a WorkerSliceConfig with most spec fields zeroed.
-
The worker-operator on the affected cluster picks up the change and reconfigures the slice with empty/zero values.
π Expected behavior
The function should return an error when copier.Copy fails. The caller should abort the reconciliation and return the error to controller-runtime for requeue with exponential backoff. The existing WorkerSliceConfig should remain untouched.
π Actual Behavior
The function silently returns an empty spec. The caller writes this to the API server, wiping the worker's slice configuration. No error is logged, no event is recorded, and no metric is incremented.
Downstream effects:
- SliceSubnet, SliceType, SliceIpamType are zeroed β the worker loses its network identity
- QoS profile is zeroed β traffic shaping is removed
- NamespaceIsolationProfile is zeroed β namespace isolation policies are dropped
- ExternalGatewayConfig is zeroed β external connectivity is broken
- The worker-operator applies these zero values, disrupting all workloads on the slice
π Relevant log output
No error is logged. The copier failure is silently discarded.
The only observable symptom is the WorkerSliceConfig on the API server
suddenly having empty/zero-valued spec fields:
$ kubectl get workersliceconfig test-slice-cluster-a -n kubeslice-my-project -o yaml
spec:
sliceName: test-slice
octet: 0
clusterSubnetCIDR: ""
sliceSubnet: "" # β was "10.1.0.0/16"
sliceType: "" # β was "Application"
# ... all other fields zeroed ...
Version
master branch (latest HEAD as of 2026-05-15). The bug exists since the initial implementation of WorkerSliceConfig reconciliation.
π₯οΈ What operating system are you seeing the problem on?
No response
β
Proposed Solution
Change the function signature to return an error, and propagate it to the caller.
Step 1: Update copySpecFromSliceConfigToWorkerSlice (lines 687β694):
func (s *WorkerSliceConfigService) copySpecFromSliceConfigToWorkerSlice(ctx context.Context,
sliceConfig controllerv1alpha1.SliceConfig) (workerv1alpha1.WorkerSliceConfig, error) {
slice := workerv1alpha1.WorkerSliceConfig{}
err := copier.Copy(&slice.Spec, &sliceConfig.Spec)
if err != nil {
return workerv1alpha1.WorkerSliceConfig{}, fmt.Errorf("failed to copy SliceConfig spec to WorkerSliceConfig: %w", err)
}
return slice, nil
}
Step 2: Update the caller at line 165:
slice, err := s.copySpecFromSliceConfigToWorkerSlice(ctx, *sliceConfig)
if err != nil {
logger.With(zap.Error(err)).Errorf("Failed to copy spec from SliceConfig to WorkerSliceConfig")
return ctrl.Result{}, err
}
workerSliceConfig.Spec = slice.Spec
This ensures the reconciler aborts and requeues on copy failure, leaving the existing WorkerSliceConfig intact.
π Have you spent some time to check if this issue has been raised before?
Code of Conduct
π Description
copySpecFromSliceConfigToWorkerSliceinservice/worker_slice_config_service.goat lines 687β694 usescopier.Copyto deep-copy the SliceConfig spec into a WorkerSliceConfig. If the copy fails, the function silently returns an emptyWorkerSliceConfig{}with a zeroed spec. The caller then overwrites the existing worker slice config with this empty spec and pushes it to the API server.The caller at lines 165β166 and 282:
If
copier.Copyfails,slice.Specis a zero-valuedWorkerSliceConfigSpec. The caller overwritesworkerSliceConfig.Specwith this empty struct, losing all existing configuration. Some fields are re-set afterward (Octet, ClusterSubnetCIDR, SliceName at lines 279β281), but critical fields from the SliceConfig spec β such asSliceType,SliceSubnet,SliceIpamType,Clusters,MaxClusters, and the entireSliceGatewayProviderβ are zeroed.π Reproduction steps
Create a SliceConfig with a full spec (QoS profile, external gateway config, namespace isolation, etc.)
Register clusters and wait for WorkerSliceConfigs to be created and fully reconciled.
Trigger a
copier.Copyfailure. While unlikely in normal operation, this can occur when:copierrelies oncopierdoesn't handle correctlyThe reconciler calls
copySpecFromSliceConfigToWorkerSlice, which returns an emptyWorkerSliceConfig{}.The caller overwrites
workerSliceConfig.Specwith the empty spec, then callsutil.UpdateResource. The API server receives a WorkerSliceConfig with most spec fields zeroed.The worker-operator on the affected cluster picks up the change and reconfigures the slice with empty/zero values.
π Expected behavior
The function should return an error when
copier.Copyfails. The caller should abort the reconciliation and return the error to controller-runtime for requeue with exponential backoff. The existing WorkerSliceConfig should remain untouched.π Actual Behavior
The function silently returns an empty spec. The caller writes this to the API server, wiping the worker's slice configuration. No error is logged, no event is recorded, and no metric is incremented.
Downstream effects:
π Relevant log output
Version
master branch (latest HEAD as of 2026-05-15). The bug exists since the initial implementation of WorkerSliceConfig reconciliation.
π₯οΈ What operating system are you seeing the problem on?
No response
β Proposed Solution
Change the function signature to return an error, and propagate it to the caller.
Step 1: Update
copySpecFromSliceConfigToWorkerSlice(lines 687β694):Step 2: Update the caller at line 165:
This ensures the reconciler aborts and requeues on copy failure, leaving the existing WorkerSliceConfig intact.
π Have you spent some time to check if this issue has been raised before?
Code of Conduct