Kubernetes manifest checker
Paste YAML and get warnings for missing limits, :latest images, root containers and other common mistakes.
Runs locally. Nothing you paste leaves this tab.
What this checks
Required fields, selectors, image tags, resources, security context, probes, host namespaces, plain-text secrets and RBAC wildcards. When you paste several documents it also checks that Services select pods, target ports exist, Ingress backends exist, HPAs have requests to scale on and replicated workloads have a PodDisruptionBudget. For CI, run kubeconform for schema validation, kube-linter or Polaris for policy, and Pluto or kubent to find API versions your cluster no longer serves.
The Pod Security Standards line shows the strictest level each workload would pass: Privileged, Baseline or Restricted.
Rules
Ignore a rule for this browser with the Ignore button, or for one object with an annotation:
metadata:
annotations:
opsmask.com/ignore: "image-tag, no-liveness"missing-fieldRequired field missing- apiVersion, kind, metadata.name, a selector and a container image are required. The API server rejects the object without them.
selector-mismatchSelector does not match pod labels- spec.selector must match spec.template.metadata.labels, otherwise the API server rejects the workload.
no-namespaceNo namespace- The object lands in whatever namespace kubectl, Helm or Argo CD targets, which can differ between people and pipelines.
secret-in-gitSecret values in the manifest- Base64 is encoding, not encryption. Anyone with access to the repo can read the value. Use External Secrets Operator, Sealed Secrets or the Secrets Store CSI driver.
plaintext-secretPlain-text secret in env or args- The value is visible in Git, in kubectl describe and in the pod spec.
public-load-balancerPublic LoadBalancer- A LoadBalancer Service gets a public IP unless the cloud-specific internal annotation is set.
node-portNodePort Service- NodePort opens the port on every node. Prefer ClusterIP behind an Ingress or an internal LoadBalancer.
ingress-no-tlsIngress without TLS- Traffic to the Ingress is plain HTTP unless TLS is terminated somewhere in front of it.
rbac-wildcardWildcard in RBAC rule- “*” in verbs, resources or apiGroups grants access to things that do not exist yet, including future CRDs. List what is needed.
single-replicaSingle replica- A node drain, cluster upgrade or crash causes downtime while the only pod is rescheduled.
no-disruption-budgetNo PodDisruptionBudget- Without a PDB a node drain can evict every replica at the same time.
no-spreadReplicas not spread- Without topology spread or anti-affinity the scheduler may put every replica on the same node or zone.
host-namespaceHost namespace shared- hostNetwork, hostPID and hostIPC remove the isolation between the pod and the node.
host-pathhostPath volume- hostPath exposes the node filesystem to the pod and is a common container escape route.
sa-tokenService account token mounted- Most apps never call the Kubernetes API. A mounted token is useful to an attacker who gets into the pod.
no-seccompNo seccomp profile- RuntimeDefault blocks dangerous syscalls and is required by the Restricted Pod Security Standard.
duplicate-nameDuplicate name- Container names must be unique in a pod. Duplicate env var names silently keep the last value.
image-tagImage uses latest or no tag- The same manifest can pull different code on different days, and rollbacks are not predictable. Pin a version or digest.
no-requestsNo resource requests- The scheduler cannot place the pod sensibly, HPA cannot compute utilisation, and the pod is first to be evicted.
no-memory-limitNo memory limit- A memory leak can starve other pods on the node. CPU limits are optional and often cause throttling.
request-over-limitRequest larger than limit- The API server rejects a container whose request is above its limit.
privilegedPrivileged container- privileged: true gives the container full access to the node.
privilege-escalationPrivilege escalation allowed- Without allowPrivilegeEscalation: false a process can gain more privileges than its parent through setuid binaries.
run-as-rootMay run as root- If the image runs as root, a container escape lands as root on the node.
writable-root-fsWritable root filesystem- A read-only root filesystem stops an attacker from dropping tools into the container. Mount an emptyDir for paths the app writes to.
capabilitiesCapabilities not dropped- Containers get a default set of Linux capabilities most apps never use.
no-readinessNo readinessProbe- Traffic reaches the pod as soon as the process starts, before the app is ready.
no-livenessNo livenessProbe- A hung process is not restarted. Keep it cheap and do not check dependencies in it.
same-probesLiveness and readiness are identical- When a dependency is down, both fail together and Kubernetes restarts pods that only needed to stop taking traffic.
probe-portProbe uses an unknown port name- A named probe port must match a name in the container’s ports, otherwise the probe always fails.
slow-startLong initialDelaySeconds- A startupProbe protects slow starts without delaying liveness checks for the rest of the pod’s life.
job-ttlJob never cleaned up- Finished Jobs and their pods stay in the cluster until deleted.
cronjob-concurrencyCronJob runs may overlap- The default concurrencyPolicy is Allow, so a slow run overlaps the next one.
cronjob-deadlineNo startingDeadlineSeconds- If the controller misses more than 100 schedules (for example during an outage) the CronJob stops scheduling.
service-no-matchService selects no pods- No workload in the pasted manifests has labels matching the Service selector, so it will have no endpoints.
service-target-portService targetPort not found- targetPort must match a containerPort (or a port name) on the selected pods.
ingress-backendIngress backend not found- The Ingress points at a Service that is not in the pasted manifests. Requests return 503 if it does not exist in the cluster.
hpa-no-requestHPA target has no requests- Utilisation is measured against requests. Without them the HPA reports <unknown> and never scales.