nektos/act · error

--userns: invalid USER mode

Error message

--userns: invalid USER mode

What it means

Error [83]: The Docker ImageInspect API call for the job image failed inside extractFromImageEnv. Act inspects the image to harvest its Dockerfile ENV variables and merge them into the job environment (special-casing PATH). Failure means the image was deleted between pull and exec, the daemon is unreachable, or the image reference is unresolvable at inspect time.

Solutions

  1. Confirm the image exists: docker image inspect <image>
  2. Re-pull explicitly: docker pull <image>, or let act pull by not preloading
  3. Verify DOCKER_HOST/socket connectivity: docker info
  4. If images are pruned by a side process, disable the prune or pull inside the job before the step runs
  5. Pin an explicit tag instead of implicit :latest to avoid surprises

Example fix

# before: image pruned mid-run, inspect fails
$ docker image prune -a -f & act run
# after
$ docker pull node:20 && act -j build
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight before invoking act programmatically
if _, err := cli.ImageInspect(ctx, image); err != nil {
	_, _ = cli.ImagePull(ctx, image, client.ImagePullOptions{})
}

Try / catch

if err := step(ctx); err != nil && strings.Contains(err.Error(), "inspect image") {
	// pull and retry once
	_ = pull(image)
	err = step(ctx)
}

Prevention

When it happens

Trigger: cr.cli.ImageInspect(ctx, cr.input.Image) erroring: image removed (docker rmi / pruned concurrently), daemon connection dropped (DOCKER_HOST tcp socket restart), or image name/tag typo when the pull step was skipped.

Common situations: Running 'docker image prune -a' in another terminal mid-run; aggressive CI cleanup scripts between jobs; DOCKER_HOST pointing at a remote socket that times out; using local images with an implicit :latest tag that was retagged.

Related errors


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/d730d1e78f0d5805. Report an issue: GitHub.

Appendix: source

Thrown at pkg/container/docker_cli.go:537

	// collect all the labels for the container
	labels, err := opts.ReadKVStrings(copts.labelsFile.GetSlice(), copts.labels.GetSlice())
	if err != nil {
		return nil, err
	}

	pidMode := container.PidMode(copts.pidMode)
	if !pidMode.Valid() {
		return nil, errors.New("--pid: invalid PID mode")
	}

	utsMode := container.UTSMode(copts.utsMode)
	if !utsMode.Valid() {
		return nil, errors.New("--uts: invalid UTS mode")
	}

	usernsMode := container.UsernsMode(copts.usernsMode)
	if !usernsMode.Valid() {
		return nil, errors.New("--userns: invalid USER mode")
	}

	cgroupnsMode := container.CgroupnsMode(copts.cgroupnsMode)
	if !cgroupnsMode.Valid() {
		return nil, errors.New("--cgroupns: invalid CGROUP mode")
	}

	restartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy)
	if err != nil {
		return nil, err
	}

	loggingOpts, err := parseLoggingOpts(copts.loggingDriver, copts.loggingOpts.GetSlice())
	if err != nil {
		return nil, err
	}

	securityOpts, err := parseSecurityOpts(copts.securityOpt.GetSlice())

View on GitHub (pinned to 4f41128141)