A friendly name duplicate error occurs when two resources have the same display name in a context where uniqueness is required. This is usually encountered with custom resources (CRs) or when using status fields that expect unique names.
Some Kubernetes resources or controllers use a "friendly name" (human-readable identifier) that must be globally unique or unique within a scope. When two resources try to use the same friendly name, the system rejects the second one to prevent ambiguity and conflicts. Common in custom resource definitions (CRDs) and third-party controllers like Ingress, Service, or custom operators.
Find what's causing the conflict:
kubectl get <resource-type> -A | grep <name>
kubectl get <resource-type> --all-namespaces
# Find exact duplicates:
kubectl get <resource-type> -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort | uniq -d
# Describe both resources:
kubectl describe <resource-type> <name> -n <ns1>
kubectl describe <resource-type> <name> -n <ns2>Identify which resource was created first.
Resolve the conflict:
Option 1: Rename the new resource
kubectl patch <resource> <old-name> -p '{"metadata":{"name":"<new-name>"}}'
# Or:
kubectl delete <resource> <old-name>
kubectl create -f updated-manifest.yaml # With new nameOption 2: Remove the old resource
kubectl delete <resource> <old-name> -n <namespace>Option 3: Use namespace isolation
# Move resource to different namespace:
kubectl create ns team-a
kubectl apply -f resource.yaml -n team-aChoose based on which resource is still needed.
Understand where names must be unique:
# Cluster-scoped (names unique across entire cluster):
kubectl api-resources | grep "<none>" # <none> = cluster scope
# Namespace-scoped (names unique per namespace):
kubectl api-resources | grep "true" # true = namespaced
# For custom resources:
kubectl get crd <name>.yaml -o jsonpath='{.spec.scope}'
# Two resources can have same name if in different namespaces (if namespaced)
kubectl get pods default/myapp # Namespace 1
kubectl get pods other/myapp # Namespace 2 (OK)Namespaced resources can have duplicate names in different namespaces.
Instead of relying on name alone, use metadata:
apiVersion: myapi.example.com/v1
kind: MyResource
metadata:
name: shared-name # Can be duplicated across namespaces
namespace: team-a
labels:
team: team-a
environment: prod
annotations:
owner: [email protected]
spec:
# ...Use selectors to query by labels:
kubectl get <resource> -l team=team-a
kubectl get <resource> -l environment=prodLabels provide flexible grouping without name collisions.
Prevent duplicates with structured names:
# Convention: <team>-<service>-<environment>
app-api-prod
app-api-staging
app-worker-prod
# Or: <project>-<component>-<version>
myapp-web-v1
myapp-web-v2
myapp-db-v1
# Enforce via kube-linter or similar:
kube-lint --allowed-registry my-registry # Custom rules
# Or via validation in CRD:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
names:
kind: MyResource
validation:
openAPIV3Schema:
properties:
metadata:
properties:
name:
pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])$" # Regex validationConsistent naming prevents conflicts.
Review resource validation rules:
# Get CRD definition:
kubectl get crd <resource>.example.com -o yaml
# Look for validation rules:
validation:
openAPIV3Schema:
properties:
spec:
properties:
friendlyName:
type: string
description: "Must be unique"
# If validation exists but isn't working, check controller logs:
kubectl logs -n <controller-ns> deployment/<controller> | grep -i "friendly\|unique"Some validations are in CRD schema, others enforced by controller.
Verify the conflict is properly caught:
# Try creating duplicate:
kubectl apply -f duplicate.yaml
# Should fail with error about duplicate name
# Check what the error message says:
kubectl apply -f duplicate.yaml 2>&1 | head -20
# If no error, enforcement might be missing
# Add validation to CRD:
kubectl patch crd <resource> --type merge -p \
'{"spec":{"validation":{"openAPIV3Schema":{"properties":{"metadata":{"properties":{"name":{"pattern\":"^unique-pattern$"}}}}}}}}'Ensure validation catches duplicates before they're stored.
Prevent future conflicts:
# Document in ConfigMap or wiki:
kubectl create configmap naming-standards \
--from-literal=convention="<team>-<service>-<env>" \
--from-literal=forbidden-prefixes="system-,kube-" \
-n kube-system
# Or in comments in manifests:
# NAMING: Resources must follow pattern: {team}-{service}-{env}
# EXAMPLE: platform-api-prod, platform-worker-stagingClear documentation reduces accidental conflicts.
Friendly name uniqueness is enforced at different levels: API server (for built-in resources), controller (for custom resources), or CRD validation. Some resources allow duplicate names if scoped properly (e.g., Services in different namespaces can have same name). For third-party controllers, read the CRD documentation for uniqueness scope. Implement namespace strategy: one namespace per team to isolate naming. Consider using owners/finalizers to ensure orphaned resources are cleaned up. For GitOps, ensure Git repo structure mirrors namespace structure to prevent conflicts during syncing.
No subnets found for EKS cluster
How to fix "eks subnet not found" in Kubernetes
unable to compute replica count
How to fix "unable to compute replica count" in Kubernetes HPA
error: context not found
How to fix "error: context not found" in Kubernetes
default backend - 404
How to fix "default backend - 404" in Kubernetes Ingress
serviceaccount cannot list resource
How to fix "serviceaccount cannot list resource" in Kubernetes