hashicorp/nomad · error
opening seccomp profile (%s) failed: %v
Error message
opening seccomp profile (%s) failed: %v
What it means
When a security_opt entry is seccomp=<profile> (other than 'unconfined'), parseSecurityOpts reads the profile file from disk and compacts its JSON before passing it to Docker. This error means os.ReadFile of the seccomp profile path failed — the file is missing, unreadable, or the path is wrong. It surfaces the errno in %v.
Source
Thrown at drivers/docker/driver.go:920
}
// takes a local seccomp daemon, reads the file contents for sending to the daemon
// this code modified slightly from the docker CLI code
// https://github.com/docker/cli/blob/8ef8547eb6934b28497d309d21e280bcd25145f5/cli/command/container/opts.go#L840
func parseSecurityOpts(securityOpts []string) ([]string, error) {
for key, opt := range securityOpts {
con := strings.SplitN(opt, "=", 2)
if len(con) == 1 && con[0] != "no-new-privileges" {
if strings.Contains(opt, ":") {
con = strings.SplitN(opt, ":", 2)
} else {
return securityOpts, fmt.Errorf("invalid security_opt: %q", opt)
}
}
if con[0] == "seccomp" && con[1] != "unconfined" {
f, err := os.ReadFile(con[1])
if err != nil {
return securityOpts, fmt.Errorf("opening seccomp profile (%s) failed: %v", con[1], err)
}
b := bytes.NewBuffer(nil)
if err := json.Compact(b, f); err != nil {
return securityOpts, fmt.Errorf("compacting json for seccomp profile (%s) failed: %v", con[1], err)
}
securityOpts[key] = fmt.Sprintf("seccomp=%s", b.Bytes())
}
}
return securityOpts, nil
}
const (
// memoryNoLimit is a sentinel value for memory_max that indicates the
// driver should not enforce a maximum memory limit
memoryNoLimit = -1
)
View on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the seccomp profile file exists on the client host at the exact absolute path given.
- Distribute the profile via provisioning (or a template/artifact to a known client path) and reference that path.
- Check file permissions so the Nomad agent user can read it.
- If no custom profile is needed, use "seccomp=unconfined" (not recommended) or drop the option to use Docker's default.
Example fix
// before
config { security_opt = ["seccomp=./profile.json"] }
// after
config { security_opt = ["seccomp=/etc/nomad.d/seccomp/profile.json"] } Defensive patterns
Strategy: validation
Validate before calling
for _, opt := range cfg.SecurityOpt {
if strings.HasPrefix(opt, "seccomp=") && !strings.HasSuffix(opt, "unconfined") {
path := strings.TrimPrefix(opt, "seccomp=")
if _, err := os.ReadFile(path); err != nil {
return fmt.Errorf("seccomp profile %s unreadable: %w", path, err)
}
}
} Try / catch
if _, err := os.ReadFile(path); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("seccomp profile missing on client: %s", path)
}
return fmt.Errorf("cannot read seccomp profile: %w", err)
} Prevention
- Provision seccomp profiles to every client node at a fixed absolute path
- Validate the profile is readable by the Nomad agent user
- Profiles live on the host, not inside the container image — never reference image paths
- Test JSON validity of the profile at deploy time
When it happens
Trigger: config.security_opt has "seccomp=/path/to/profile.json" but the file does not exist on the Nomad client, the task lacks read permission, or a relative path resolves against the wrong working directory. Raised in createContainerConfig.
Common situations: Seccomp profile not shipped to the client node (only present in the job dir, not at the absolute path used), typo in the path, permissions tightened by hardening, or referencing a profile inside the container image (unavailable on host).
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- running container as ContainerAdmin is unsafe; change the co
- path escapes the alloc directory
- file path escapes capture directory
- file path %q escapes capture directory %q
- unable to open image archive: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/b5d453ca502498ec.
Report an issue: GitHub.