kube-linter lint: Catch Misconfigurations
kube-linter lint <path> scans manifests and Helm charts for misconfigurations like missing resource limits or running as root, and exits non-zero on findings.
kubeconform checks that a manifest is structurally valid; kube-linter checks whether it is a good idea. It flags reliability and security smells the schema cannot.
What it does
kube-linter lint runs a set of checks (no resource requests/limits, runs as non-root, latest tag, missing liveness/readiness probes, and more) against YAML manifests or a Helm chart directory. Each failing object is reported with the check name and remediation.
Common usage
kube-linter lint deployment.yaml
kube-linter lint ./chart/ # Helm chart directory
kube-linter lint --config .kube-linter.yaml manifests/
kube-linter lint --format json manifests/ | jq '.Reports'Options
| Flag | What it does |
|---|---|
| lint <path> | Lint a file, directory, or Helm chart |
| --config <file> | Config selecting which checks run |
| --include / --exclude | Enable or disable specific checks by name |
| --format | Output format: plain, json, sarif |
| --fail-if-no-objects-found | Error when no objects are detected |
| checks list | Print all built-in checks |
In CI
Commit a .kube-linter.yaml so the enabled checks are reproducible across runs and laptops. Use --format sarif to surface findings in the GitHub code-scanning UI. kube-linter exits non-zero when any check fails, gating the merge.
Common errors in CI
no valid objects found (with --fail-if-no-objects-found) means the path had no parseable manifests, often a glob that did not expand. unknown check "<name>" in --include is a typo; run kube-linter checks list for the exact names. A chart that fails to render shows error rendering Helm chart, usually a missing values file.
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