E-NO
Kubernetes Seccomp configuration 7 Min Read

Kubernetes Seccomp Configuration Mistakes: A Practical Guide

calendar_today Published: 2026-08-26
update Last Updated: 2026-08-26
analytics SEO Efficiency: 97%
Technical guide illustration for Kubernetes Seccomp Configuration Mistakes: A Practical Guide.

Intro

Kubernetes seccomp configuration mistakes can silently break applications or expose workloads to unnecessary risk. Seccomp (secure computing mode) is a Linux kernel feature that restricts the system calls a process can make, providing a critical layer of defense for containers. However, even experienced platform teams stumble when enabling seccomp: a missing profile file on one node will prevent pods from starting, an overly restrictive policy can crash an application at 3 a.m., and an unnoticed Unconfined setting can leave a container wide open.

This guide helps practitioners avoid the most common pitfalls when enabling and configuring seccomp in Kubernetes. You will learn how to validate profiles, implement changes safely, verify enforcement, and roll back when needed. Each section includes concrete commands, configuration snippets, and expected outputs so you can apply the guidance directly to your own clusters. By following the practical examples and checklists, you can integrate seccomp into your security posture with confidence and without unnecessary downtime.

Version and Environment Inventory

Before configuring seccomp, understand your Kubernetes and container runtime versions, because support and defaults vary significantly across releases. For example, seccomp became generally available in Kubernetes 1.19, but the seccompProfile field in the Pod security context has been beta since 1.19 and stable since 1.25. The container runtime also matters: containerd, CRI-O, and Docker all support seccomp, but the way you configure default profiles differs. Skipping this inventory step is a common source of confusion when a profile works on one node but fails on another.

Prerequisites

  • Kubernetes cluster version 1.19 or later (seccomp GA in 1.19; recommend 1.25+ for stable API).
  • Container runtime that supports seccomp: containerd 1.3+, CRI-O 1.17+, or Docker 19.03+ with appropriate configuration.
  • Ability to create or edit Pod security contexts and seccomp profiles.
  • Access to cluster logs and node filesystem for debugging.
  • kubectl and jq installed on your workstation for querying pod specs.

Check Kubernetes Version

Run the following command to check the Kubernetes server version:

kubectl version --short

Expected output (example):

Client Version: v1.27.3
Server Version: v1.27.3

If your server version is below 1.19, seccomp is not supported in the same way, and you should upgrade before proceeding. If you are on 1.19 through 1.24, the seccompProfile field is beta and may require enabling a feature gate in some managed distributions, so verify with your provider.

Verify Container Runtime Seccomp Support

For containerd, check the runtime configuration. On a node, inspect the containerd config file (commonly /etc/containerd/config.toml). Ensure the default seccomp profile is enabled. Here is a minimal relevant section:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  SystemdCgroup = true
  NoNewPrivileges = true
  # Seccomp is enabled by default if not disabled.

If you see a line like disable_seccomp = true, then seccomp is turned off for all containers using that runtime. Remove or set it to false and restart containerd:

sudo systemctl restart containerd

For Docker, seccomp is enabled by default with the default profile. You can verify by running a container and checking its seccomp status:

docker info | grep seccomp

Expected output:

Security Options:
  seccomp
  Profile: default

Inventory Existing Seccomp Usage

List pods with seccomp profiles applied using a custom script or manual inspection. Here is a quick way using kubectl and jq:

kubectl get pods -A -o json | jq -r '.items[] | select(.spec.securityContext.seccompProfile != null) | .metadata.namespace + "/" + .metadata.name'

If no pods use seccomp, the output will be empty. Otherwise, you will see a list of pods with seccomp profiles. This inventory is useful for understanding your current exposure and for planning a rollout. You may also want to check container-level security contexts, not just pod-level:

kubectl get pods -A -o json | jq -r '.items[] | . as $pod | .spec.containers[]? | select(.securityContext.seccompProfile != null) | $pod.metadata.namespace + "/" + $pod.metadata.name + " (container: " + .name + ")"'

Safe Configuration Path

A scoped implementation approach minimizes risk. Start with a single workload in a non-production namespace, gradually expanding after validation. This section walks through the process step by step with concrete examples.

Understand Seccomp Profile Types

Kubernetes supports three seccomp profile types:

  • RuntimeDefault: Uses the container runtime's default seccomp profile. This is the recommended starting point because it balances security and compatibility. The default profile typically blocks around 44 syscalls and is maintained by the runtime project.
  • Localhost: Uses a custom profile file present on the node under /var/lib/kubelet/seccomp/. This gives you fine-grained control but requires you to manage the file on every node.
  • Unconfined: Disables seccomp entirely. This should be avoided unless absolutely necessary because it removes the syscall filtering layer.

Step 1: Apply RuntimeDefault to a Test Pod

Create a simple pod manifest test-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: seccomp-test
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: test
    image: busybox
    command: ["sleep", "3600"]

Apply it:

kubectl apply -f test-pod.yaml

Verify the pod is running without issues:

kubectl get pod seccomp-test

Expected result: the pod status is Running. If it is not, check events with kubectl describe pod seccomp-test to diagnose. This simple test confirms that the runtime default profile does not interfere with your basic workload.

Step 2: Create a Custom Seccomp Profile

Custom profiles allow fine-grained control. Here is an example profile custom-profile.json that denies the chmod syscall while allowing everything else by default:

{
  "defaultAction": "SCMP_ACT_ALLOW",
  "architectures": [
    "SCMP_ARCH_X86_64",
    "SCMP_ARCH_X86",
    "SCMP_ARCH_X32"
  ],
  "syscalls": [
    {
      "names": ["chmod"],
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}

Place this file on each node in the cluster at /var/lib/kubelet/seccomp/custom-profile.json. Ensure the file is readable by the kubelet. Typically, the kubelet runs as root, but check permissions with:

sudo chmod 644 /var/lib/kubelet/seccomp/custom-profile.json

If you have many nodes, use a configuration management tool like Ansible, Puppet, or a DaemonSet to distribute the file. A common mistake is to place the profile on only one node and then wonder why pods fail to schedule on other nodes. In a multi-node cluster, you must copy the file to every node that might run the pod.

Step 3: Test the Custom Profile with a Pod

Modify the pod manifest to use the localhost profile:

apiVersion: v1
kind: Pod
metadata:
  name: seccomp-custom-test
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: custom-profile.json
  containers:
  - name: test
    image: busybox
    command: ["sleep", "3600"]

Apply and test:

kubectl apply -f seccomp-custom-test.yaml
kubectl exec -it seccomp-custom-test -- chmod 777 /tmp

Expected output: the chmod command fails with Operation not permitted because the syscall is blocked. The pod itself remains running. This confirms that the custom profile is being enforced. For example:

chmod: /tmp: Operation not permitted
command terminated with exit code 1

Step 4: Gradually Expand

After validating the profile on the test pod, consider applying it to a set of similar workloads in a staging namespace. Monitor for any failures before moving to production. A practical approach is to use a label selector on your Deployment and patch the security context. For example, if you have a Deployment named webapp in the staging namespace:

kubectl patch deployment webapp -n staging -p '{"spec":{"template":{"spec":{"securityContext":{"seccompProfile":{"type":"RuntimeDefault"}}}}}}'

Then watch the rollout:

kubectl rollout status deployment/webapp -n staging

If the rollout succeeds and the application behaves normally, you can replace RuntimeDefault with your custom localhost profile in a subsequent patch. Always have a rollback plan, which we cover in a later section.

Quick check 1 of 2

What is the Kubernetes version requirement for seccomp to be generally available?

The reference states that seccomp became generally available in Kubernetes 1.19.

Verification and Diagnostics

Verifying that seccomp is enforced and diagnosing issues are essential. Use the following techniques.

Check Pod Security Context

Inspect the running pod's security context to confirm seccomp is set:

kubectl get pod seccomp-custom-test -o jsonpath='{.spec.securityContext.seccompProfile}'

Expected output for a localhost profile:

{"type":"Localhost","localhostProfile":"custom-profile.json"}

For a container-level setting, use:

kubectl get pod seccomp-custom-test -o jsonpath='{.spec.containers[0].securityContext.seccompProfile}'

Test Syscall Blocking

Use kubectl exec to run a command that should be blocked. For our custom profile that denies chmod:

kubectl exec seccomp-custom-test -- chmod 777 /tmp

Expected output:

chmod: /tmp: Operation not permitted

This confirms the profile is active. You can also test with a syscall that should be allowed to ensure the profile is not overly broad. For example, ls /tmp should succeed:

kubectl exec seccomp-custom-test -- ls /tmp

Inspect Container Runtime Logs

If a pod fails to start due to seccomp, check the runtime logs on the node. For containerd:

journalctl -u containerd | grep seccomp

Look for messages indicating profile loading errors or syscall denials. For example:

level=error msg="failed to load seccomp profile" error="open /var/lib/kubelet/seccomp/custom-profile.json: no such file or directory"

For Docker, check:

journalctl -u docker | grep seccomp

Examine Pod Events

Use kubectl describe pod <pod-name> to see events related to seccomp failures, such as failed container creation with a message about an invalid seccomp profile. For example:

Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Warning  Failed     10s   kubelet            Error: failed to generate container "test" spec: failed to generate seccomp spec: unable to load seccomp profile "/var/lib/kubelet/seccomp/custom-profile.json": open /var/lib/kubelet/seccomp/custom-profile.json: no such file or directory

This event clearly indicates a missing profile file on the node.

Failure Modes and Recovery

Despite careful planning, failures can occur. Understanding common failure modes helps in quick recovery. This section enumerates the most frequent issues and provides step-by-step remediation.

Common Failure Modes

  1. Missing Profile File: For Localhost profiles, if the file is not present on the node, the container will fail to start with an error like cannot load seccomp profile. This often happens when profiles are manually copied to only some nodes.
  2. Invalid Profile JSON: Syntax errors in the JSON, such as a missing comma or an unknown action, can cause profile parsing failures. The pod will fail with a similar error to the missing file case.
  3. Overly Restrictive Profile: Blocking necessary syscalls can cause applications to crash at runtime. For example, blocking openat will prevent the application from reading any file, and blocking clone will prevent it from creating threads or processes.
  4. Incompatible Architecture: Profiles specifying architectures not supported by the host may cause issues. If your node is ARM64 but the profile only lists SCMP_ARCH_X86_64, the profile may fail to load or behave unexpectedly.
  5. Kernel Version Mismatch: Some seccomp actions, such as SCMP_ACT_LOG (which logs the syscall but allows it), require newer kernel versions. If the kernel does not support the action, the profile will be rejected.

Recovery Steps

If a pod fails to start, first check the pod status and events:

kubectl describe pod <pod-name>

For a missing profile file, the event will show an error similar to:

Error: failed to generate container "..." spec: failed to generate seccomp spec: unable to load seccomp profile "/var/lib/kubelet/seccomp/custom-profile.json": open /var/lib/kubelet/seccomp/custom-profile.json: no such file or directory

If the error is due to invalid JSON, the message may say failed to parse seccomp profile or similar.

Rollback to RuntimeDefault

To recover quickly, change the pod's seccomp profile to RuntimeDefault or remove it entirely. Update the manifest and apply:

securityContext:
  seccompProfile:
    type: RuntimeDefault

Or for an existing deployment, patch:

kubectl patch deployment myapp -p '{"spec":{"template":{"spec":{"securityContext":{"seccompProfile":{"type":"RuntimeDefault"}}}}}}'

This will trigger a rolling update with the safer profile. You can also patch to Unconfined if you need an immediate escape hatch, but that should be temporary and followed by a proper fix.

Verify Rollback Success

Check that pods are running and no seccomp-related events are occurring:

kubectl get pods -l app=myapp
kubectl describe pod <new-pod>

Ensure the pod is Running and no error events are present. You can also verify the seccomp profile on the new pod:

kubectl get pod <new-pod> -o jsonpath='{.spec.securityContext.seccompProfile}'

Expected output for RuntimeDefault:

{"type":"RuntimeDefault"}

Common Mistakes and How to Avoid Them

In addition to the failure modes above, here are some subtle mistakes that practitioners often make when configuring seccomp in Kubernetes.

Mistake 1: Assuming RuntimeDefault Is Always the Best

RuntimeDefault is a good starting point, but it is not a silver bullet. The default profile varies between container runtimes and versions. For example, Docker's default profile may differ from containerd's default. If you need consistent behavior across your cluster, consider creating a custom profile that is explicitly defined and version controlled.

Mistake 2: Not Testing in a Staging Environment

Many teams move straight to production with a custom profile and then discover that the application needs a syscall that was blocked. Always test in a staging environment that mirrors production as closely as possible. Use tools like strace to capture the syscalls your application makes under normal load, and then construct your profile accordingly.

Mistake 3: Forgetting to Update Profiles After Application Changes

Applications evolve, and new features may require additional syscalls. If you do not update your seccomp profile when you update the application, you may introduce failures. Make seccomp profile review a part of your change management process.

Mistake 4: Placing Custom Profiles Only on Some Nodes

As mentioned earlier, a Localhost profile must exist on every node that can run the pod. In a cluster with node auto-scaling or heterogeneous node pools, it is easy to miss a node. Use a DaemonSet or configuration management to ensure the file is present on all nodes.

Mistake 5: Using Unconfined Unnecessarily

Setting seccompProfile.type: Unconfined disables seccomp for that pod or container. This should be avoided unless you have a very specific reason, such as a legacy application that cannot run under any profile. Even then, consider using a custom profile with SCMP_ACT_ALLOW as the default action to explicitly document what is allowed.

Mistake 6: Ignoring Container-Level Settings

Seccomp can be set at the pod level or at the individual container level. If both are set, the container-level setting overrides the pod-level setting. This can lead to surprises if you expect all containers in a pod to have the same profile. Be explicit about where you set seccomp and audit both levels.

Quick check 2 of 2

Which Linux kernel feature does Kubernetes use to filter system calls?

The passage lists seccomp as a feature that filters system calls a process can make.

Advanced Topics

Once you are comfortable with basic seccomp configuration, you can explore more advanced techniques to improve security and manageability.

Using seccomp Profiles with Audit Logging

Newer kernels support the SCMP_ACT_LOG action, which logs the syscall but does not block it. This is useful during profile development to discover which syscalls an application uses without breaking it. For example, you can start with a profile that logs all syscalls and then gradually convert them to SCMP_ACT_ALLOW or SCMP_ACT_ERRNO. Note that SCMP_ACT_LOG requires kernel 4.14 or later and container runtime support.

Example snippet:

{
  "defaultAction": "SCMP_ACT_LOG",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": []
}

Apply this profile to a test pod and watch the runtime logs to see the syscalls being made. Then, build a profile that allows the necessary syscalls and blocks everything else with a default deny.

Using OCI Runtime Spec Annotations

For advanced control, you can use the OCI runtime spec annotations directly in the pod manifest. However, this is not recommended for most users because it is less portable and may be deprecated. If you need this level of control, consult your container runtime documentation.

Integrating seccomp with Policy Engines

Policy engines like Open Policy Agent (OPA) Gatekeeper or Kyverno can enforce seccomp policies across your cluster. For example, you can write a policy that requires all pods to have a seccomp profile set and rejects any pod that uses Unconfined. This helps maintain consistency and prevents misconfigurations. A simple Kyverno policy might look like this:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-seccomp
spec:
  validationFailureAction: enforce
  rules:
  - name: check-seccomp
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Seccomp profile must be set to RuntimeDefault or Localhost"
      pattern:
        spec:
          securityContext:
            seccompProfile:
              type: "RuntimeDefault | Localhost"

This is a powerful way to ensure that no workload runs without seccomp.

Operations Checklist

Use the following checklist for ongoing operations and reviews of seccomp configurations.

Pre-Deployment Checklist

  • [ ] Confirm Kubernetes version supports seccomp (>=1.19, recommend 1.25+).
  • [ ] Verify container runtime seccomp support and default profile.
  • [ ] Identify target workloads and their required syscalls (use strace or audit logs).
  • [ ] Create or obtain seccomp profiles and test them in a staging environment.
  • [ ] Ensure custom profiles are present on all relevant nodes with correct permissions (e.g., 644).
  • [ ] Set up monitoring for pod restarts and seccomp-related events.

During Deployment

  • [ ] Start with a small pilot (one pod or a single namespace).
  • [ ] Apply RuntimeDefault first, then gradually use custom profiles.
  • [ ] Monitor application logs for unexpected syscall denials.
  • [ ] Use monitoring tools to track pod restarts and errors.
  • [ ] Keep a rollback plan ready (e.g., patch to RuntimeDefault).

Post-Deployment Verification

  • [ ] Verify seccomp profile is set in pod spec (pod-level and container-level).
  • [ ] Test blocked syscalls produce expected errors (e.g., chmod fails with Operation not permitted).
  • [ ] Check runtime logs for seccomp-related messages.
  • [ ] Ensure no unexpected application errors in logs.

Regular Review

  • [ ] Periodically audit seccomp profiles for necessary changes due to application updates.
  • [ ] Re-test profiles in staging before production changes.
  • [ ] Keep documentation of profiles and their purpose.
  • [ ] Review pod security contexts for accidental Unconfined settings using a query like:
  kubectl get pods -A -o json | jq -r '.items[] | select(.spec.securityContext.seccompProfile.type == "Unconfined") | .metadata.namespace + "/" + .metadata.name'

Incident Response

  • [ ] If a pod fails, immediately rollback to RuntimeDefault or remove seccomp.
  • [ ] Investigate the cause and adjust the profile accordingly.
  • [ ] Re-deploy with corrected profile after testing.
  • [ ] Document the incident and update the profile and runbooks.

Conclusion

Seccomp is a valuable security control, but misconfigurations can cause disruption. By understanding the common mistakes, following a safe configuration path, verifying enforcement, and having recovery plans, you can effectively use seccomp to harden your Kubernetes workloads.

Start with RuntimeDefault, gradually introduce custom profiles on a small scale, and always have a rollback plan. Use the provided checklists to maintain a robust seccomp posture as your cluster evolves. Remember that seccomp is just one layer of defense; combine it with other security controls such as restricted pod security standards, non-root containers, and network policies for a comprehensive security strategy. With careful planning and testing, seccomp can significantly reduce the attack surface of your containerized applications without sacrificing reliability.

Related Research

Article Quality Score

Reader usefulness 97%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL