Skip to content
Latchkey

Crossplane XRD "cannot establish control" in CI

An XRD tells Crossplane to create a composite (XR) CRD and, optionally, a claim CRD. If the XRD schema is invalid or clashes with an existing CRD, the XRD stays Established False and the XR kind is never served.

What this error means

After applying an XRD, kubectl get xrd shows ESTABLISHED False (or OFFERED False), and applying an XR of that kind fails with "no matches for kind".

crossplane
cannot apply rendered composite resource definition CRD:
CustomResourceDefinition.apiextensions.k8s.io "xstorages.example.org" is invalid:
spec.versions[0].schema.openAPIV3Schema.properties[spec].properties[size].type:
Required value: must specify a type

Common causes

An invalid OpenAPI schema in the XRD

A property is missing a type, or the schema is otherwise malformed, so the generated CRD is rejected by the API server.

A conflicting CRD already owns the name

Another CRD (or a previous XRD version) already defines the same group/kind, so the XRD cannot establish control of it.

How to fix it

Fix the schema so every property has a type

  1. Read the API server rejection to find the property path.
  2. Add the missing type (and required fields) to the XRD schema.
  3. Re-apply and wait for ESTABLISHED True.
Terminal
kubectl wait --for condition=Established --timeout=120s \
  xrd/xstorages.example.org

Remove the conflicting CRD or rename the XRD

If an existing CRD owns the name, delete the stale one or change the XRD group/kind so it does not collide.

Terminal
kubectl get crd xstorages.example.org -o jsonpath='{.metadata.ownerReferences}'

How to prevent it

  • Validate XRDs with crossplane beta validate before applying.
  • Give every schema property an explicit type.
  • Avoid reusing a group/kind already owned by another CRD.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →