docker/cli · error

--env-file

Error message

--env-file: %w

What it means

Returned in opts.go:509 when opts.ReadKVEnvStrings fails while reading --env-file entries (combined with inline --env values). The wrapped %w is the file-read or parse error from the env-file loader.

Solutions

  1. Check the file path exists and is readable: ls -l <path>.
  2. Ensure every line is KEY=VALUE (or KEY), with valid key characters ([A-Za-z_][A-Za-z0-9_]*).
  3. Strip BOM/CRLF; use unix line endings.
  4. Remove or quote problematic lines.

Example fix

# before: env.list contains a line '=FOO'
docker run --env-file env.list alpine

# after: env.list contains 'FOO=bar'
docker run --env-file env.list alpine
Defensive patterns

Strategy: validation

Validate before calling

// Read and validate the env-file before passing it to docker:
for _, p := range envFiles {
    f, err := os.Open(p)
    if err != nil { return fmt.Errorf("env-file unreadable: %w", err) }
    defer f.Close()
    sc := bufio.NewScanner(f)
    for sc.Scan() {
        line := strings.TrimSpace(sc.Text())
        if line == "" || strings.HasPrefix(line, "#") { continue }
        if !strings.Contains(line, "=") && !envKeyRe.MatchString(line) {
            return fmt.Errorf("bad env line: %q", line)
        }
    }
}

Try / catch

// File/parse errors are deterministic; fix the file rather than retry.
if err != nil && strings.Contains(err.Error(), "--env-file") {
    /* surface offending file/line */
}

Prevention

When it happens

Trigger: `docker run --env-file <path>` where the file is missing/unreadable, or contains a line that does not conform to the KEY=VALUE / KEY parsing rules, or a line is malformed.

Common situations: Wrong file path, permission denied reading the file, BOM/encoding issues, a line like `=VALUE` (empty key), or invalid characters in a key.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/0975a8579a75b135. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/container/opts.go:509

		if cdi.IsQualifiedName(device) {
			cdiDeviceNames = append(cdiDeviceNames, device)
			continue
		}
		validated, err := validateDevice(device, serverOS)
		if err != nil {
			return nil, err
		}
		deviceMapping, err := parseDevice(validated, serverOS)
		if err != nil {
			return nil, err
		}
		deviceMappings = append(deviceMappings, deviceMapping)
	}

	// collect all the environment variables for the container
	envVariables, err := opts.ReadKVEnvStrings(copts.envFile.GetSlice(), copts.env.GetSlice())
	if err != nil {
		return nil, fmt.Errorf("--env-file: %w", err)
	}

	// collect all the labels for the container
	labels, err := opts.ReadKVStrings(copts.labelsFile.GetSlice(), copts.labels.GetSlice())
	if err != nil {
		return nil, fmt.Errorf("--label-file: %w", 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")
	}

View on GitHub (pinned to 4f84911bfe)