docker/cli · error

password is empty

Error message

password is empty

What it means

Thrown by verifyLoginFlags when the --password flag was explicitly changed but resolves to an empty string, e.g. 'docker login -u user --password ""'. The flag-level guard (lines 86-87) treats an explicitly-empty password as invalid.

Solutions

  1. Provide a non-empty password or, preferably, use --password-stdin.
  2. Verify the secret/env var is populated before running the command.

Example fix

# before
docker login -u user --password ""
# after
PASS=${PASS:?empty}; printf '%s' "$PASS" | docker login -u user --password-stdin
Defensive patterns

Strategy: validation

Validate before calling

// Reject an explicitly empty --password
if flags.Changed("password") && strings.TrimSpace(opts.password) == "" {
    return fmt.Errorf("--password must not be empty")
}

Prevention

When it happens

Trigger: Running 'docker login -u user --password ""' or '--password=' with an empty value at the flag-parsing stage.

Common situations: Passing an unset shell variable as the password: 'docker login -u user -p $EMPTY'; misconfigured CI secret that resolves to empty.

Related errors


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

Appendix: source

Thrown at cli/command/registry/login.go:87

}

// verifyLoginFlags validates flags set on the command.
//
// TODO(thaJeztah); combine with verifyLoginOptions, but this requires rewrites of many tests.
func verifyLoginFlags(flags *pflag.FlagSet, opts loginOptions) error {
	if flags.Changed("password-stdin") || opts.password == "-" {
		if flags.Changed("password") && opts.password != "-" {
			return errors.New("conflicting options: cannot specify both --password and --password-stdin")
		}
		if !flags.Changed("username") {
			return errors.New("the --password-stdin option requires --username to be set")
		}
	}
	if flags.Changed("username") && opts.user == "" {
		return errors.New("username is empty")
	}
	if flags.Changed("password") && opts.password == "" {
		return errors.New("password is empty")
	}
	return nil
}

// readSecretFromStdin reads the secret from r and returns it as a string.
// It trims terminal line-endings (LF, CRLF, or CR), which may be added when
// inputting interactively or piping input. The value is otherwise treated as
// opaque, preserving any other whitespace, including newlines, per [NIST SP 800-63B §5.1.1.2].
// Note that trimming whitespace may still happen elsewhere (see [NIST SP 800-63B (revision 4) §3.1.1.2]);
//
// > Verifiers **MAY** make limited allowances for mistyping (e.g., removing
// > leading and trailing whitespace characters before verification, allowing
// > the verification of passwords with differing cases for the leading character)
//
// [NIST SP 800-63B §5.1.1.2]: https://pages.nist.gov/800-63-3/sp800-63b.html#memsecretver
// [NIST SP 800-63B (revision 4) §3.1.1.2]: https://pages.nist.gov/800-63-4/sp800-63b.html#passwordver
func readSecretFromStdin(r io.Reader) (string, error) {
	b, err := io.ReadAll(r)

View on GitHub (pinned to 4f84911bfe)