nektos/act · error

conflicting options: cannot attach both user-defined and non

Error message

conflicting options: cannot attach both user-defined and non-user-defined network-modes

What it means

Error [92]: In copyDir, after walking the source directory into a temp tar file, rewinding it with Seek(0, 0) failed. The temp file (os.CreateTemp) handle became invalid — the file was deleted or closed underneath, or an fs error occurred. Very rare; usually indicates filesystem trouble on the host running act.

Source

Thrown at pkg/container/docker_cli.go:812

		if err != nil {
			return nil, err
		}
		if _, ok := endpoints[n.Target]; ok {
			return nil, fmt.Errorf("network %q is specified multiple times", n.Target)
		}

		// For backward compatibility: if no custom options are provided for the network,
		// and only a single network is specified, omit the endpoint-configuration
		// on the client (the daemon will still create it when creating the container)
		if i == 0 && len(copts.netMode.Value()) == 1 {
			if ep == nil || reflect.ValueOf(*ep).IsZero() {
				continue
			}
		}
		endpoints[n.Target] = ep
	}
	if hasUserDefined && hasNonUserDefined {
		return nil, errors.New("conflicting options: cannot attach both user-defined and non-user-defined network-modes")
	}
	return endpoints, nil
}

func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOptions) error { //nolint:gocyclo
	// TODO should we error if _any_ advanced option is used? (i.e. forbid to combine advanced notation with the "old" flags (`--network-alias`, `--link`, `--ip`, `--ip6`)?
	if len(n.Aliases) > 0 && copts.aliases.Len() > 0 {
		return errors.New("conflicting options: cannot specify both --network-alias and per-network alias")
	}
	if len(n.Links) > 0 && copts.links.Len() > 0 {
		return errors.New("conflicting options: cannot specify both --link and per-network links")
	}
	if n.IPv4Address.IsValid() && copts.ipv4Address != nil {
		return errors.New("conflicting options: cannot specify both --ip and per-network IPv4 address")
	}
	if n.IPv6Address.IsValid() && copts.ipv6Address != nil {
		return errors.New("conflicting options: cannot specify both --ip6 and per-network IPv6 address")
	}

View on GitHub (pinned to 4f41128141)

Solutions

  1. Point TMPDIR to a stable location: TMPDIR=$PWD/.tmp act ...
  2. Raise fd limit: ulimit -n 4096 before running act
  3. Ensure /tmp has space and isn't aggressively cleaned (df -h /tmp)
  4. Exclude huge directories from the workspace (.gitignore is honored by copyDir; ignore build artifacts) to shorten the walk

Example fix

# before
act -j build   # /tmp janitor deletes temp tar
# after
mkdir -p .tmp && TMPDIR=$PWD/.tmp act -j build
Defensive patterns

Strategy: validation

Validate before calling

// Ensure TMPDIR stable & writable before running act
if d := os.Getenv("TMPDIR"); d != "" {
	if fi, err := os.Stat(d); err != nil || !fi.IsDir() { log.Fatal("bad TMPDIR") }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to seek tar archive") {
	// rerun with TMPDIR set to a stable local dir
}

Prevention

When it happens

Trigger: tarFile.Seek failing: /tmp cleaned by a janitor process mid-run, file handle closed early under load, NFS/tmpfs issues on the host, or fd exhaustion causing EBADF.

Common situations: /tmp cleanup (systemd-tmpfiles) racing act's run; CI runners with tiny /tmp; hosts with ulimit -n too low for big workspace walks; /tmp mounted with noexec/weird options.

Related errors


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