Skip to main content
This page covers the most common install and runtime issues. For everything else, gather the diagnostic bundle described at the bottom and open a support thread.

Contents

Install & scheduling Uninstall & cleanup Metrics & observability Getting help

Engine pod is Pending

Almost always a node-selector mismatch. The engine DaemonSet selects nodes labeled nvidia.com/gpu.present=true by default — if no node carries that label, no pod is scheduled.
If you use a different label in your environment, override the selector instead:
my-values.yaml

Pod stuck in ContainerCreating (CDI)

The pod scheduled onto a GPU node (so it’s past 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:
GPU Operator v25.10.0+ enables CDI by default — no patch needed.
Confirm it’s CDI and not something else: kubectl describe pod <pod> — a CDI problem shows a Failed to create … CDI device injection / unresolvable CDI devices event. A missing-image event (ImagePullBackOff) or volume-mount error points elsewhere.

Engine pod CreateContainerError on OpenShift

The pod is requesting hostIPC but its ServiceAccount is not bound to an SCC that permits it. Add openshift.enabled: true to your values file and upgrade:
See Install on OpenShift for the full overlay and for the “bring your own SA” pattern.

Operator pod ImagePullBackOff

The image lives in a registry your cluster cannot authenticate to. Create an image pull secret and reference it from the chart:
my-values.yaml
For air-gapped clusters, mirror the operator image into your internal registry and override operator.image.repository and operator.image.tag.

Install fails with CRD ... exists and cannot be imported

The 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.
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 of helm.sh/resource-policy: keep.
Existing LMCacheEngine CRs survive — only the CRD’s ownership annotations change.
The LMCacheEngine CRD is cluster-scoped — one of it exists for the whole cluster. Helm tracks which release owns each resource via three stamps:The adoption commands rewrite those stamps so your new release becomes the recognized owner. The CRD’s schema, any existing 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 no LMCacheEngine CRs exist anywhere on the cluster. Confirm first:
Deleting the CRD cascade-deletes every LMCacheEngine CR on the cluster. Use Option A if you have any CRs you want to keep.

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.
Removing finalizers bypasses any cleanup the operator would have performed on backing resources. Use only when the operator is definitively gone.
If 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
Or grant the scraping ServiceAccount the system:auth-delegator ClusterRole so it can authenticate with the kube-apiserver TokenReview API:

CRD survives uninstall (by design)

The LMCacheEngine 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 normal helm uninstall path doesn’t apply — for example:
  • helm list -A shows no release, but the engine pod, LMCacheEngine CR, services, and CRD are still present (the release record was removed but its resources weren’t).
  • helm uninstall hangs, or kubectl delete namespace gets stuck in Terminating.
The root cause is almost always the same: the 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:
1

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.
2

Delete the namespace

With the finalizer cleared, this completes instead of hanging — it sweeps the DaemonSet, pods, services, ConfigMaps, ServiceAccounts, and RoleBindings.
3

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).
4

Sweep orphaned cluster-scoped RBAC

The operator’s ClusterRole/ClusterRoleBinding are cluster-scoped and survive a namespace delete. Remove any leftovers:
Order matters. Clear the finalizer before deleting the namespace. If you delete the namespace first, it gets stuck in Terminating (blocked on the un-drainable CR) until you clear the finalizer anyway.
After these four steps, 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:
Rare hashing fallback: if LMCache logs that it is using builtin hash instead of the default blake3 path, set PYTHONHASHSEED=0 in the vLLM pod and restart it. This is not the normal MP requirement and it is unrelated to MQ payload-shape mismatches.

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.