{"record":{"id":"f635d53431d8ce5b","repo":"derailed/k9s","slug":"unable-to-assert-crd-servers-versions-for-s","errorCode":null,"errorMessage":"unable to assert CRD servers versions for %s","messagePattern":"unable to assert CRD servers versions for (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/render/crd.go","lineNumber":101,"sourceCode":"\tr.ID = client.MetaFQN(&crd.ObjectMeta)\n\tr.Fields = model1.Fields{\n\t\tcrd.Spec.Names.Plural,\n\t\tcrd.Spec.Group,\n\t\tcrd.Spec.Names.Kind,\n\t\tnaStrings(versions),\n\t\tstring(crd.Spec.Scope),\n\t\tnaStrings(crd.Spec.Names.ShortNames),\n\t\tmapToStr(crd.GetLabels()),\n\t\tAsStatus(c.diagnose(crd.Name, crd.Spec.Versions)),\n\t\tToAge(crd.GetCreationTimestamp()),\n\t}\n\n\treturn nil\n}\n\nfunc (CustomResourceDefinition) diagnose(n string, vv []v1.CustomResourceDefinitionVersion) error {\n\tif len(vv) == 0 {\n\t\treturn fmt.Errorf(\"unable to assert CRD servers versions for %s\", n)\n\t}\n\n\tvar (\n\t\tee     []error\n\t\tserved bool\n\t)\n\tfor _, v := range vv {\n\t\tif v.Served {\n\t\t\tserved = true\n\t\t}\n\t\tif v.Deprecated {\n\t\t\tif v.DeprecationWarning != nil {\n\t\t\t\tee = append(ee, fmt.Errorf(\"%s\", *v.DeprecationWarning))\n\t\t\t} else {\n\t\t\t\tee = append(ee, fmt.Errorf(\"%s[%s] is deprecated\", n, v.Name))\n\t\t\t}\n\t\t}\n\t}","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/render/crd.go#L83-L119","documentation":"CustomResourceDefinition.diagnose flags a CRD whose spec.versions slice is empty. The API server normally guarantees at least one version, so encountering this means a malformed or exotic CRD object (or a stale cache entry), not ordinary operation.","triggerScenarios":"A CRD applied through non-validating paths (direct etcd edit, buggy operators) with versions: []; a cached informer object from an interrupted CRD replacement.","commonSituations":"Operator or CRD-controller bugs emitting incomplete CRDs; tooling that patches spec.versions to an empty list; viewing a CRD mid-deletion.","solutions":["Inspect the object: kubectl get crd <name> -o yaml and check spec.versions","Re-apply or patch the CRD with at least one version (served: true)","Delete and recreate the CRD if its definition is corrupt","Refresh the k9s view to drop stale cache entries"],"exampleFix":"# before: spec.versions: []\n# after\nspec:\n  versions:\n  - name: v1\n    served: true\n    storage: true","handlingStrategy":"validation","validationCode":"if len(crd.Spec.Versions) == 0 {\n\t// skip / quarantine this CRD object instead of diagnosing\n\treturn\n}","typeGuard":null,"tryCatchPattern":"Treat the diagnose error as display data (row status); optionally re-fetch the CRD once to bypass a stale cache before trusting it.","preventionTips":["Always apply CRDs through kubectl/manifests so API validation runs","Alert on CRDs with empty versions — they indicate writer bugs","Refresh informer caches after CRD replacement operations"],"tags":["crd","kubernetes-api","validation"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}