cilium/cilium · error
failed to create CiliumEnvoyConfig for service: %w
Error message
failed to create CiliumEnvoyConfig for service: %w
What it means
This error is returned by the Cilium operator's createOrUpdateEnvoyConfig when the Kubernetes client's Create call for a desired CiliumEnvoyConfig resource fails. The CEC is the resource that configures Envoy load balancing for a service of type LoadBalancer, so this means the operator could not materialize the required Envoy config object. The original API server error is wrapped with %w so it can be inspected with errors.Is/As.
Source
Thrown at operator/pkg/ciliumenvoyconfig/ciliumenvoyconfig_reconcile.go:118
return nil
}
// Update existing CEC
updated := existing.DeepCopy()
updated.Spec = desired.Spec
scopedLog.DebugContext(ctx, "Updating CiliumEnvoyConfig")
if err := r.client.Update(ctx, updated); err != nil {
return fmt.Errorf("failed to update CiliumEnvoyConfig for service: %w", err)
}
scopedLog.DebugContext(ctx, "Updated CiliumEnvoyConfig for service")
return nil
}
scopedLog.DebugContext(ctx, "Creating CiliumEnvoyConfig")
if err := r.client.Create(ctx, desired); err != nil {
return fmt.Errorf("failed to create CiliumEnvoyConfig for service: %w", err)
}
scopedLog.DebugContext(ctx, "Created CiliumEnvoyConfig for service")
return nil
}
func (r *ciliumEnvoyConfigReconciler) deleteEnvoyConfig(ctx context.Context, svc *corev1.Service) error {
existing := ciliumv2.CiliumEnvoyConfig{}
if err := r.client.Get(ctx, types.NamespacedName{Namespace: svc.Namespace, Name: fmt.Sprintf("%s-%s", ciliumEnvoyLBPrefix, svc.Name)}, &existing); err != nil {
if !k8serrors.IsNotFound(err) {
return fmt.Errorf("failed to lookup CiliumEnvoyConfig: %w", err)
}
return nil
}
r.logger.DebugContext(ctx, "Deleting CiliumEnvoyConfig")
if err := r.client.Delete(ctx, &existing); err != nil {
return fmt.Errorf("failed to delete CiliumEnvoyConfig for service: %w", err)View on GitHub (pinned to ac7b90affa)
Solutions
- Verify the cilium.io_v2 CRDs (including CiliumEnvoyConfig) are installed and up to date with your Cilium version: kubectl get crd ciliumenvoyconfigs.cilium.io
- Check the wrapped error with errors.Is(err, k8serrors.IsAlreadyExists) — if it races with creation, the reconciler will normally retry; ensure no conflicting manually created CEC with the same '<prefix>-<svc>' name exists
- Confirm the operator's RBAC/ClusterRole allows create/update on ciliumenvoyconfigs.cilium.io
- Check API server connectivity/health (kubectl get, operator logs for throttling) and re-trigger reconciliation
Example fix
// before
if err := r.client.Create(ctx, desired); err != nil {
return fmt.Errorf("failed to create CiliumEnvoyConfig for service: %w", err)
}
// after
err := r.client.Create(ctx, desired)
if k8serrors.IsAlreadyExists(err) {
if err := r.client.Update(ctx, desired); err != nil {
return fmt.Errorf("failed to update existing CiliumEnvoyConfig: %w", err)
}
return nil
}
if err != nil {
return fmt.Errorf("failed to create CiliumEnvoyConfig for service: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
const crd = await k8sApi.getApiResources(); if (!crd.resources.some(r => r.name === 'ciliumenvoyconfigs.cilium.io')) throw new Error('CiliumEnvoyConfig CRD not installed'); Type guard
function isStatusError(err: unknown): err is { response?: { statusCode: number }; reason?: string } { return typeof err === 'object' && err !== null && 'response' in err; } Try / catch
try { await reconciler.reconcile(svc); } catch (err) { if (k8s.isAlreadyExists(err)) { /* reconcile expected race; safe to retry via controller backoff */ } else { log.error('CEC create failed', err); throw err; } } Prevention
- Ensure cilium.io CRDs are installed before deploying the operator
- Grant operator RBAC create/update/get on ciliumenvoyconfigs.cilium.io
- Treat AlreadyExists as retryable, not fatal
- Monitor API server availability during service churn
When it happens
Trigger: r.client.Create(ctx, desired) returns an error while reconciling a service — e.g. the CiliumEnvoyConfig CRD is not installed, an object with the same name exists with different spec (AlreadyExists race), the namespace is forbidden, or the object exceeds validation limits.
Common situations: Cilium Envoy config mode enabled in an older cluster missing the cilium.io CiliumEnvoyConfig CRD; two controllers racing to create the same CEC (AlreadyExists); RBAC denies the operator create on ciliumenvoyconfigs; api-server outage or timeouts during mass service creation.
Related errors
- failed to delete CiliumCIDRGroup %s: %w
- ⚠️ unable to restart Cilium Operator pods: %w
- unable to create CiliumNetworkPolicy %s: %w
- unable to retrieve CRD %s: %w
- unable to retrieve CiliumLocalRedirectPolicy %s: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/fe135314708dbe65.
Report an issue: GitHub.