hashicorp/nomad · error

compacting json for seccomp profile (%s) failed: %v

Error message

compacting json for seccomp profile (%s) failed: %v

What it means

This error is raised in parseSecurityOpts when a docker driver task supplies a `seccomp=<path>` security option pointing to a JSON seccomp profile file. The driver reads the file and compacts (minifies) the JSON before passing it to the Docker daemon; if json.Compact fails, the JSON is malformed. Nomad aborts container creation so the daemon never receives an invalid profile.

Source

Thrown at drivers/docker/driver.go:924

// 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
)

// memoryLimits computes the memory and memory_reservation values passed along
// to the docker host config. These fields represent hard limit (cgroup
// memory.max) and memory reservation (cgroup memory.low) from docker's
// perspective, respectively.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Validate the profile with `jq . /path/to/profile.json` (or `python -m json.tool`) and fix the reported syntax error.
  2. Remove comments and trailing commas — raw JSON forbids both; use a JSONC-to-JSON converter if the source has comments.
  3. Verify the path in security_opt points to the correct file readable by the Nomad client, and the file is not empty or truncated.
  4. Regenerate the profile from a known-good source, e.g. `docker run --rm alpine seccomp-dump` or moby's default profile, then re-run the task.

Example fix

// task docker config
// before
security_opt = ["seccomp=/etc/nomad/seccomp.json"]  // file contains // comments
// after: strip comments / fix syntax so `jq . /etc/nomad/seccomp.json` succeeds, then keep
security_opt = ["seccomp=/etc/nomad/seccomp.json"]
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
function validateSeccompProfile(path) {
  const raw = fs.readFileSync(path, 'utf8');
  JSON.parse(raw); // throws on invalid JSON, mirroring json.Compact
  return true;
}

Type guard

function isSeccompOpt(opt) {
  return typeof opt === 'string' && opt.startsWith('seccomp=');
}

Try / catch

try {
  validateSeccompProfile(profilePath);
} catch (e) {
  throw new Error(`seccomp profile ${profilePath} is not valid JSON: ${e.message}`);
}

Prevention

When it happens

Trigger: Setting security_opt = ["seccomp=/path/to/profile.json"] in the task's docker driver config where the file contains invalid JSON (trailing commas, comments, single quotes, truncated file, or non-JSON content).

Common situations: Hand-written seccomp profiles with JSON syntax mistakes; profiles copied from tutorials containing comments (JSON has none); a partially-uploaded or empty profile file; generating the profile with a tool that emits JSONC.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/2a2897aa6376ea26. Report an issue: GitHub.