nektos/act · error
compacting json for seccomp profile (%s) failed: %w
Error message
compacting json for seccomp profile (%s) failed: %w
What it means
Thrown while converting a seccomp profile security option for a container. act supports the special values 'unconfined' and 'default'; any other value is treated as a path to a file containing the seccomp profile JSON, which is read and compacted with json.Compact before being passed to Docker. This error means the file was read successfully but its content is not valid JSON, so json.Compact failed.
Source
Thrown at pkg/container/docker_cli.go:959
}
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.
func parseSystemPaths(securityOpts []string) (filtered, maskedPaths, readonlyPaths []string) {
filtered = securityOpts[:0]
for _, opt := range securityOpts {
if opt == "systempaths=unconfined" {View on GitHub (pinned to 4f41128141)
Solutions
- Validate the profile file with a JSON parser: jq . /path/to/profile.json or python -m json.tool
- Re-download or regenerate the seccomp profile from a trusted source (e.g. moby/default-seccomp.json)
- Use the built-in values --security-opt seccomp=unconfined or seccomp=default if a custom profile is not required
- Ensure the path is to a regular file containing the raw JSON profile, not YAML or a wrapper script
Example fix
# before --security-opt seccomp=./my-profile.yaml # after --security-opt seccomp=./my-profile.json # jq . my-profile.json must succeed
Defensive patterns
Strategy: validation
Validate before calling
# shell, before running act
f=$(printf '%s' "$opts" | grep -oP '(?<=seccomp=)\S+' || true)
[ -n "$f" ] && [ "${f##*/}" != "unconfined" ] && [ "${f##*/}" != "default" ] && jq empty "$f" Prevention
- Keep seccomp profiles in JSON (not YAML) and lint them with jq in CI
- Generate profiles from trusted sources instead of hand-editing
- Never point seccomp= at a URL or directory
When it happens
Trigger: Setting the container option --security-opt seccomp=<path> where <path> is neither 'default' nor 'unconfined', and the referenced file exists but contains malformed JSON (truncated profile, YAML instead of JSON, HTML error page, BOM, or comments).
Common situations: User points seccomp at a Docker/OCI profile downloaded partially, edited by hand, saved as YAML, or references a file with a UTF-8 BOM. Also happens when the path accidentally resolves to a directory or non-profile file that is still readable.
Related errors
- network-scoped aliases are only supported for user-defined n
- invalid storage option
- valid streams are STDIN, STDOUT and STDERR
- %s is not a valid mac address
- network %q is specified multiple times
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/92233a5b9ea7bce3.
Report an issue: GitHub.