docker/cli · error

error reading from

Error message

error reading from %s: %w

What it means

Returned by readSecretData (secret/create.go:149) wrapping the error from sequential.Open when the supplied file path cannot be opened. This is the file-open failure path; it fires before any bytes are read. The filename is interpolated so the message names the offending path.

Solutions

  1. Verify the file path exists and is readable before running the command.
  2. Use an absolute path to avoid working-directory ambiguity.
  3. Check file permissions if you get a permission-denied cause.

Example fix

// before
docker secret create mysecret ./secrets/db.pass   # wrong cwd
// after
docker secret create mysecret /srv/secrets/db.pass
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the secret file is openable before creating the secret.
func validateSecretFile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return fmt.Errorf("cannot open secret file %q: %w", path, err)
    }
    return f.Close()
}

Type guard

// fileExists reports whether path is openable for reading.
func fileExists(path string) bool {
    f, err := os.Open(path)
    if err != nil { return false }
    _ = f.Close()
    return true
}

Prevention

When it happens

Trigger: Running `docker secret create mysecret /path/that/does/not/exist` or pointing at a file with no read permission. The open call fails and is wrapped with %w.

Common situations: Wrong path, typo, file not yet created, permission denied, or a relative path resolved against an unexpected working directory.

Related errors


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

Appendix: source

Thrown at cli/command/secret/create.go:149

			return nil, fmt.Errorf("error reading from STDIN: %w", err)
		}
		if len(data) == 0 {
			return nil, errors.New("error reading from STDIN: data is empty")
		}
		return data, nil
	case "":
		return nil, errors.New("secret file is required")
	default:
		// Open file with [FILE_FLAG_SEQUENTIAL_SCAN] on Windows, which
		// prevents Windows from aggressively caching it. We expect this
		// file to be only read once. Given that this is expected to be
		// a small file, this may not be a significant optimization, so
		// we could choose to omit this, and use a regular [os.Open].
		//
		// [FILE_FLAG_SEQUENTIAL_SCAN]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN
		f, err := sequential.Open(fileName)
		if err != nil {
			return nil, fmt.Errorf("error reading from %s: %w", fileName, err)
		}
		defer f.Close()
		data, err := io.ReadAll(io.LimitReader(f, 2*maxSecretSize))
		if err != nil {
			return nil, fmt.Errorf("error reading from %s: %w", fileName, err)
		}
		if len(data) == 0 {
			return nil, fmt.Errorf("error reading from %s: data is empty", fileName)
		}
		return data, nil
	}
}

View on GitHub (pinned to 4f84911bfe)