cilium/cilium · error
refusing to overwrite synced Secret %s/%s without ownership
Error message
refusing to overwrite synced Secret %s/%s without ownership labels
What it means
ensureOwnedBy also validates the existing (target) Secret: if it lacks ownership labels, the sync refuses to overwrite it, because overwriting an unlabeled secret could clobber a secret not managed by the sync (or one whose ownership history was lost). This is a safety guard against hijacking pre-existing secrets.
Source
Thrown at operator/pkg/secretsync/ownership.go:51
}
return types.NamespacedName{Namespace: namespace, Name: name}, true
}
func isOwnedBy(obj client.Object, owner types.NamespacedName, namespaceLabel, nameLabel string) bool {
existingOwner, ok := ownerFromLabels(obj, namespaceLabel, nameLabel)
return ok && existingOwner == owner
}
func ensureOwnedBy(existing, desired client.Object, namespaceLabel, nameLabel string) error {
desiredOwner, ok := ownerFromLabels(desired, namespaceLabel, nameLabel)
if !ok {
return fmt.Errorf("desired synced Secret %s/%s is missing ownership labels", desired.GetNamespace(), desired.GetName())
}
existingOwner, ok := ownerFromLabels(existing, namespaceLabel, nameLabel)
if !ok {
return fmt.Errorf("refusing to overwrite synced Secret %s/%s without ownership labels", existing.GetNamespace(), existing.GetName())
}
if existingOwner != desiredOwner {
return fmt.Errorf("refusing to overwrite synced Secret %s/%s owned by %s/%s with data from %s/%s", existing.GetNamespace(), existing.GetName(), existingOwner.Namespace, existingOwner.Name, desiredOwner.Namespace, desiredOwner.Name)
}
return nil
}
func setSourceAnnotations(obj client.Object, kind string, source types.NamespacedName) {
annotations := make(map[string]string, len(obj.GetAnnotations())+3)
maps.Copy(annotations, obj.GetAnnotations())
annotations[SourceKindAnnotation] = kind
annotations[SourceNamespaceAnnotation] = source.Namespace
annotations[SourceNameAnnotation] = source.Name
obj.SetAnnotations(annotations)
}View on GitHub (pinned to ac7b90affa)
Solutions
- Delete the unlabeled conflicting Secret and let the sync recreate it with proper ownership labels
- Re-add the correct Cilium ownership labels to the existing Secret
- Rename your pre-existing Secret or the synced Secret to avoid the collision
- Verify ownership label keys match the current Cilium version's expectations
Example fix
# before kubectl create secret generic my-secret ... # collides with synced name # after kubectl delete secret my-secret -n ns && kubectl annotate secret ... # or rename to my-secret-manual
Defensive patterns
Strategy: validation
Validate before calling
existing := &corev1.Secret{}
err := cl.Get(ctx, key, existing)
if err == nil && !isOwnershipLabeled(existing, namespaceLabel, nameLabel) {
return fmt.Errorf("conflict: secret %s exists without cilium ownership labels; rename or delete it first", key)
} Type guard
func isOwnershipLabeled(o client.Object, nsLabel, nameLabel string) bool {
l := o.GetLabels()
_, ns := l[nsLabel]; _, n := l[nameLabel]
return ns && n
} Try / catch
if err := ensureSyncedSecret(ctx, cl, reg, key); err != nil {
if strings.Contains(err.Error(), "without ownership labels") {
// delete the unlabeled secret (after confirming it is not user-managed), then retry
}
return err
} Prevention
- Avoid pre-creating Secrets with the names cilium will sync into
- After upgrades that change label keys, re-run the sync registration to relabel existing secrets
- Document that cilium-synced Secrets are managed objects and must not be hand-edited
When it happens
Trigger: ensureSyncedSecret finds an existing Secret in the cluster whose labels do not contain the ownership keys, and attempts to overwrite it with desired content.
Common situations: A same-named Secret pre-exists (created manually or by another controller) before cilium's sync runs; labels were stripped by another tool; or an upgrade changed the label keys so old secrets appear unlabeled.
Related errors
- failed to setup secret sync reconciler: %w
- desired synced Secret %s/%s is missing ownership labels
- ⚠️ unable to restart Cilium Operator pods: %w
- failed to get features status from %s: %w
- failed to collect Cilium etcd secret: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/b3e4dc02588526e5.
Report an issue: GitHub.