kube-linter lint: Static Checks for Manifests
kube-linter lint runs a configurable set of static checks against Kubernetes YAML and Helm charts, exiting non-zero when any enabled check reports a finding.
KubeLinter (invoked as kube-linter lint) is StackRoxs static analyzer for manifests. It ships checks for things like non-root containers, read-only root filesystems, and missing resource requests, all runnable offline in a PR gate.
What it does
kube-linter lint takes paths to YAML files, directories, or Helm charts and runs enabled checks against the parsed resources. Each finding names the check, object, and remediation. Any finding causes a non-zero exit. A YAML config selects which checks run and defines custom ones.
Common usage
# lint a directory of manifests
kube-linter lint ./manifests
# lint a Helm chart directory
kube-linter lint ./chart
# use a config and emit SARIF for code scanning
kube-linter lint --config .kube-linter.yaml \
--format sarif ./manifests > results.sarifOptions
| Flag | What it does |
|---|---|
| --config <file> | YAML config selecting/tuning checks (.kube-linter.yaml) |
| --include <check> | Enable a specific check by name; repeatable |
| --exclude <check> | Disable a specific check; repeatable |
| --format <fmt> | Output format: plain, json, sarif |
| --add-all-built-in | Enable every built-in check |
| --fail-on-invalid-resource | Fail if a resource cannot be parsed |
In CI
Commit a .kube-linter.yaml so the check set is versioned and reproducible offline. Use --format sarif to upload findings to GitHub code scanning. Run kube-linter list-checks locally to see available checks before enabling or excluding them in the config.
Common errors in CI
A finding prints like "manifests/deploy.yaml: (object: <ns>/app apps/v1, Kind=Deployment) container \"app\" does not have a read-only root file system (check: no-read-only-root-fs, ...)" and the process exits 1. "Error: no valid objects found" means the path had no parseable manifests, often un-rendered Helm templates. "unknown check" in the config means a typo in an --include/--exclude name.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes