Skip to content

lookout state storage

When a PersistentVolumeClaim sits Pending and the pod behind it will not schedule — name the reason: a StorageClass that does not exist, no class and no cluster default, a static-only class with nothing pre-provisioned, plus the default-class ambiguity and stranded volumes behind it.

MCP tool: k8s_storage_binding

Terminal window
lookout state storage [flags]
FlagTypeDefaultMeaning
--namespacestring—limit the scan to one namespace
-Abool—scan all namespaces
--workloadstring—target one workload as <Kind>/<namespace>/<name>, e.g. Deployment/prod/api
--sinceduration—how far back to look (0 = command default)
--formatstringlogfmtoutput format: logfmt|json (one record per line either way)
--timeoutduration10sabort the invocation after this long (exit 1)
--kubeconfigstring—path to a kubeconfig file, instead of $KUBECONFIG / ~/.kube/config
--contextstring—kubeconfig context to read, instead of its current-context. Selects a cluster for THIS invocation only — nothing is written back — so concurrent invocations can target different clusters. Reported as context=<name> in the summary line
--exemptionsstring—path to a git-reviewed exemption file (YAML); covered findings are ANNOTATED with their reason and expiry and counted as exempt=<n> in the summary, never dropped

Every kind= this command can emit, and the severities it carries them at. Nothing else appears in its output; a kind absent from a run means the check looked and found nothing. See the finding-kind glossary for the whole vocabulary.

KindSeverityClaim
storage.missing_classcriticalthe claim names a StorageClass that does not exist — it will stay Pending forever
storage.no_default_classcriticalthe claim names no class and the cluster has no default StorageClass
storage.no_provisionerwarningthe claim’s class is static-only (kubernetes.io/no-provisioner) and no matching PV is available
storage.multiple_defaultswarningmore than one StorageClass is annotated as the cluster default; which one wins is not defined
storage.pv_failedwarninga PersistentVolume is Failed: its reclaim did not complete, so the backing disk stays allocated and the volume cannot be reused
storage.pv_releasedinfoa PersistentVolume is Released — retained on purpose, but its capacity is unusable until spec.claimRef is cleared

Beyond the shared envelope fields (kind, severity, namespace, kind_of_object, name, reason, message, fingerprint, exempt_reason, exempt_expires):

FieldMeaning
storage_classStorageClass the claim names, or the class the finding is about
classesStorageClasses the cluster does have, sorted (empty when there are none)
defaultsStorageClasses annotated as the cluster default, sorted
provisionerthe class’s spec.provisioner
phasethe claim’s or volume’s status.phase at scan time
requestedstorage the claim requests (spec.resources.requests.storage)
capacitythe volume’s spec.capacity.storage
reclaim_policythe volume’s spec.persistentVolumeReclaimPolicy
claimthe claim the volume was bound to, as namespace/name
binding_modethe class’s volumeBindingMode (Immediate when unset)

Output: one finding per line (logfmt; —format=json for one JSON object per line), keys in fixed order; healthy resources emit nothing. The final line is always the summary: scanned= findings= elapsed= — findings=0 with a summary present means “scanned and healthy”; a stream without a summary line is void. Exit 0 data, 1 runtime error (diagnostics on stderr only), 2 usage.

Terminal window
lookout state storage
lookout state storage --namespace=prod
lookout state storage --format=json