cilium/cilium · error

failed to create or update ServiceImport: %w

Error message

failed to create or update ServiceImport: %w

What it means

createOrUpdateServiceImport uses controller-runtime's CreateOrUpdate (via the reconcile helper) to create or patch the local ServiceImport; if that call fails for any reason the error is wrapped as "failed to create or update ServiceImport: %w" and returned to Reconcile, where it triggers backoff/requeue. Common underlying causes are API server conflicts, validation rejections, or RBAC denials on the ServiceImport resource.

Source

Thrown at pkg/clustermesh/mcsapi/serviceimport_controller.go:739

	return controllerruntime.Success()
}

func (r *mcsAPIServiceImportReconciler) createOrUpdateServiceImport(ctx context.Context, desiredSvcImport *mcsapiv1beta1.ServiceImport) (*mcsapiv1beta1.ServiceImport, error) {
	svcImport := &mcsapiv1beta1.ServiceImport{
		ObjectMeta: metav1.ObjectMeta{
			Name:      desiredSvcImport.Name,
			Namespace: desiredSvcImport.Namespace,
		},
	}

	result, err := controllerutil.CreateOrUpdate(ctx, r.Client, svcImport, func() error {
		svcImport.Annotations = desiredSvcImport.Annotations
		svcImport.Labels = desiredSvcImport.Labels
		svcImport.Spec = desiredSvcImport.Spec
		return nil
	})
	if err != nil {
		return nil, fmt.Errorf("failed to create or update ServiceImport: %w", err)
	}

	r.Logger.Debug(fmt.Sprintf("ServiceImport %s has been %s", client.ObjectKeyFromObject(svcImport), result))

	return svcImport, nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *mcsAPIServiceImportReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&mcsapiv1beta1.ServiceImport{}).
		// Watch for changes to ServiceExport
		Watches(&mcsapiv1beta1.ServiceExport{}, &handler.EnqueueRequestForObject{}).
		// Watch for changes to Services
		Watches(&corev1.Service{}, &handler.EnqueueRequestForObject{}).
		// Watch for changes to Namespace to requeue service imports and exports
		Watches(&corev1.Namespace{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []ctrl.Request {
			requests := []ctrl.Request{}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Inspect the wrapped error: conflict (409) → retry is automatic via requeue; check status cause otherwise.
  2. Verify the ServiceImport CRD is installed and the reconciler's client has get/create/update RBAC on mcsapi resources.
  3. If conflicts recur, reduce concurrent writers or ensure the mutate function is idempotent and only touches owned fields.
  4. Check API server health and client cache freshness if errors are sporadic.

Example fix

// before: mutate clobbers foreign fields causing repeated conflicts
svcImport.Annotations = desiredSvcImport.Annotations
svcImport.Spec = desiredSvcImport.Spec

// after: only set owned annotations, keep others
if svcImport.Annotations == nil {
    svcImport.Annotations = map[string]string{}
}
for k, v := range desiredSvcImport.Annotations {
    svcImport.Annotations[k] = v
}
svcImport.Spec = desiredSvcImport.Spec
Defensive patterns

Strategy: retry

Validate before calling

// preflight: CRD present and RBAC allows update
if _, err := client.Resource(mcsapiGVR).Namespace(ns).Get(ctx, name, metav1.GetOptions{}); apierrors.IsNotFound(err) && !crdInstalled {
    return errors.New("ServiceImport CRD not installed")
}

Try / catch

svcImport, err := createOrUpdateServiceImport(ctx, r, desired)
if err != nil {
    if apierrors.IsConflict(err) {
        return ctrl.Result{RequeueAfter: time.Second}, nil // transient, requeue
    }
    if apierrors.IsForbidden(err) {
        log.Error("RBAC denies ServiceImport update", "err", err) // do not hot-loop
    }
    return ctrl.Result{}, fmt.Errorf("failed to create or update ServiceImport: %w", err)
}

Prevention

When it happens

Trigger: The CreateOrUpdate mutate/update round trip errors: the object was modified concurrently (optimistic conflict), the ServiceImport spec failed API validation, the client lacked update permission, or the API server was unreachable.

Common situations: Frequent reconciles racing with another controller writing the same ServiceImport; stale cached object causing conflict on update; CRD not installed so the resource kind is missing; namespace/RBAC misconfiguration.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/1c2e5e587f18540d. Report an issue: GitHub.