docker/cli · error
opening seccomp profile
Error message
opening seccomp profile (%s) failed: %w
What it means
Thrown by parseSecurityOpts when seccomp=<filename> is used and os.ReadFile cannot read that file. The CLI reads the local seccomp profile file to send its JSON content to the daemon, so the file must exist and be readable by the user running docker.
Solutions
- Verify the path exists and is a file: ls -l /path/to/profile.json
- Use an absolute path to avoid working-directory ambiguity
- Fix permissions so the user invoking docker can read it (chmod +r or adjust ownership)
- If the file is under a restricted home dir and you run via sudo, copy it to a world-readable location
Example fix
# before docker run --security-opt seccomp=~/profiles/custom.json ... # after docker run --security-opt seccomp=/home/user/profiles/custom.json ...
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the seccomp profile file is readable before invoking docker.
profile := "/path/to/profile.json"
info, err := os.Stat(profile)
if err != nil || info.IsDir() {
return fmt.Errorf("seccomp profile not readable: %w", err)
}
// optional: attempt a read to confirm permissions
if _, err := os.ReadFile(profile); err != nil {
return err
} Prevention
- Always pass absolute paths for seccomp profiles
- In CI, assert the profile file exists as a build step before the docker run
- Store profiles in a version-controlled, world-readable location
When it happens
Trigger: Calling `docker run --security-opt seccomp=/path/to/profile.json` where the path does not exist, is a directory, or the invoking user lacks read permission. os.ReadFile returns an os.PathError wrapped into this error.
Common situations: Relative path that resolves against an unexpected working directory; profile deleted/moved; SELinux/AppArmor blocking access; misspelled path; running docker via sudo where the file is only readable by the non-root user.
Related errors
- failed to generate key for
- failed to write public key to
- refusing to load key from
- error importing key from
- private key file must not be readable or writable by others
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/1fe3fd8ad627f38c.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/container/opts.go:948
for key, opt := range securityOpts {
k, v, ok := strings.Cut(opt, "=")
if !ok && k != "no-new-privileges" {
k, v, ok = strings.Cut(opt, ":")
}
if (!ok || v == "") && k != "no-new-privileges" {
// "no-new-privileges" is the only option that does not require a value.
return securityOpts, fmt.Errorf("invalid --security-opt: %q", opt)
}
if k == "seccomp" {
switch v {
case seccompProfileDefault, seccompProfileUnconfined:
// known special names for built-in profiles, nothing to do.
default:
// value may be a filename, in which case we send the profile's
// content if it's valid JSON.
f, err := os.ReadFile(v)
if err != nil {
return securityOpts, fmt.Errorf("opening seccomp profile (%s) failed: %w", v, err)
}
var b bytes.Buffer
if err := json.Compact(&b, f); err != nil {
return securityOpts, fmt.Errorf("compacting json for seccomp profile (%s) failed: %w", v, err)
}
securityOpts[key] = "seccomp=" + b.String()
}
}
}
return securityOpts, nil
}
// parseSystemPaths checks if `systempaths=unconfined` security option is set,
// and returns the `MaskedPaths` and `ReadonlyPaths` accordingly. An updated
// list of security options is returned with this option removed, because the
// `unconfined` option is handled client-side, and should not be sent to the
// daemon.View on GitHub (pinned to 4f84911bfe)