Contents
Install & scheduling- Engine pod is
Pending— node-selector / GPU label mismatch - Pod stuck in
ContainerCreating— CDI disabled (older NVIDIA GPU Operator) - Engine pod
CreateContainerErroron OpenShift — missing privileged SCC - Operator pod
ImagePullBackOff— registry auth / air-gap - Install fails with
CRD ... exists and cannot be imported— ownership conflict from a prior install
helm uninstallhangs — stuck CR finalizer- CRD survives uninstall (by design)
- Cleaning up an inconsistent or orphaned install — no release record / orphaned resources
- Metrics endpoint returns
401 - OTel Collector / traces not flowing → see Observability → Troubleshooting
Engine pod is Pending
nvidia.com/gpu.present=true by default — if no node carries that label, no pod is
scheduled.
my-values.yaml
Pod stuck in ContainerCreating (CDI)
Pending) but the container can’t be
created. The usual cause on NVIDIA GPU clusters is that the Container Device Interface
(CDI) is disabled. The NVIDIA GPU Operator injects GPUs via CDI, and before GPU
Operator v25.10.0 it defaulted to cdi.enabled: false — with no obvious error, the pod
just hangs in ContainerCreating.
Enable CDI in the GPU ClusterPolicy:
Engine pod CreateContainerError on OpenShift
hostIPC but its ServiceAccount is not bound to an SCC that permits
it. Add openshift.enabled: true to your values file and upgrade:
Operator pod ImagePullBackOff
my-values.yaml
operator.image.repository and operator.image.tag.
Install fails with CRD ... exists and cannot be imported
LMCacheEngine CRD is cluster-scoped — there is only one of it. A previous install
under a different release name (or namespace) annotated it as its own; Helm refuses to
silently transfer ownership to your new release. This is a Helm-wide safety check, not
specific to this chart — cert-manager, kube-prometheus-stack, and Argo CD all behave
identically.
Before doing either fix below, check whether the prior release is still active:
helm list -A. If you see a real release that owns the CRD, leave it alone — running a
second operator against the same CRD will fight reconciliation. Use the existing release
(helm upgrade <its-name> ...) instead.Option A — adopt the CRD into your new release (recommended)
Use this when the prior release is gone (was uninstalled, or is on a cluster you don’t own anymore) but the CRD survived because ofhelm.sh/resource-policy: keep.
LMCacheEngine CRs survive — only the CRD’s ownership annotations change.
What do these commands actually do?
What do these commands actually do?
The
The adoption commands rewrite those stamps so your new release becomes the recognized
owner. The CRD’s schema, any existing
LMCacheEngine CRD is cluster-scoped — one of it exists for the whole cluster. Helm
tracks which release owns each resource via three stamps:| Field | Purpose |
|---|---|
annotation meta.helm.sh/release-name | which release owns this |
annotation meta.helm.sh/release-namespace | in which namespace |
label app.kubernetes.io/managed-by=Helm | ”some Helm release manages this” |
LMCacheEngine CRs, and everything in any
namespace are unchanged — it’s a pure metadata edit, fully reversible by running the
same commands with the old values.Option B — delete the CRD and let the install recreate it
Safe only when noLMCacheEngine CRs exist anywhere on the cluster. Confirm first:
helm uninstall hangs
The pre-delete hook is waiting for the LMCacheEngine CR’s finalizer to drain. Usually
this means the operator was already gone when the CR was deleted, so nobody is running the
finalizer.
helm list -A shows no release at all (the operator and the release record are
already gone, not just a stuck uninstall), this quick fix doesn’t apply — follow
Cleaning up an inconsistent or orphaned install
for the full manual teardown.
Metrics endpoint returns 401
The controller-runtime auth filter is on by default. Either disable it for scrapers that
cannot authenticate:
my-values.yaml
system:auth-delegator ClusterRole so it can
authenticate with the kube-apiserver TokenReview API:
CRD survives uninstall (by design)
TheLMCacheEngine CRD is annotated helm.sh/resource-policy: keep, so helm uninstall
leaves it (and any remaining CRs) in place. This is the same convention used by
cert-manager and kube-prometheus-stack — it prevents data loss when you upgrade in place.
To remove the CRD and cascade-delete any remaining CRs:
Cleaning up an inconsistent or orphaned install
Use this when the normalhelm uninstall path doesn’t apply — for example:
helm list -Ashows no release, but the engine pod,LMCacheEngineCR, services, and CRD are still present (the release record was removed but its resources weren’t).helm uninstallhangs, orkubectl delete namespacegets stuck inTerminating.
LMCacheEngine CR carries a finalizer
(lmcache.ai/cleanup) that only the operator can drain. If the operator is gone — or
was removed before the CR — nothing runs the finalizer, so the CR can’t be deleted, and
anything waiting on it (a namespace delete, an uninstall hook) blocks indefinitely.
Clean up manually, in this order:
Clear the stuck CR's finalizer
The operator isn’t coming back to drain it, so remove the finalizer yourself:(Find the name with
kubectl get lmcacheengine -A.) This is safe only when the
operator is definitively gone — it skips the cleanup the operator would have done,
which is fine when you’re tearing everything down anyway.Delete the namespace
With the finalizer cleared, this completes instead of hanging — it sweeps the
DaemonSet, pods, services, ConfigMaps, ServiceAccounts, and RoleBindings.
Delete the CRD
Cluster-scoped, so the namespace delete didn’t touch it. Removing it gives a clean
slate (and avoids the ownership conflict on the next install).
kubectl get ns <namespace> and
kubectl get crd lmcacheengines.lmcache.lmcache.ai should both return NotFound — a true
clean slate.
Gathering a diagnostic bundle
When opening a support thread, include:Next steps
Helm install reference
Re-check the install steps against the chart’s documented values.
Getting Started
Re-validate prerequisites if multiple issues are stacking up.

