docker/cli · error
password is empty
Error message
password is empty
What it means
Raised by verifyLoginFlags (cli/command/registry/login.go:87) when the --password/-p flag was explicitly set but its value is an empty string. An explicitly empty password is rejected at parse time instead of being sent to the registry or triggering a prompt.
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 e9452d6e78)
Solutions
- Confirm the password variable is non-empty before use: docker login -u user -p "${PASS:?PASS is empty}" (or better, switch to --password-stdin)
- Prefer --password-stdin, which both avoids the process-list exposure warning and gives a clearer failure mode: printf '%s' "$PASS" | docker login -u user --password-stdin
- If the value comes from a command substitution, run that command separately first and check its exit code and output
Example fix
# before (PASS unset → empty flag value)
docker login -u user -p "$PASS" registry.example.com
# after
printf '%s' "${PASS:?PASS is empty}" | docker login -u user --password-stdin registry.example.com When it happens
Trigger: docker login -u user -p '' registry.example.com; docker login --password="" — pflag reports the flag as Changed while opts.password is "". Most often docker login -p "$PASS_VAR" with PASS_VAR empty or unset.
Common situations: Empty CI secrets (secret not available to the branch/fork running the job); credential-fetch commands substituted inline that failed silently, e.g. -p "$(vault read ... )" returning nothing; .env files not loaded before the login step.
Related errors
- username is empty
- conflicting options: cannot specify both --password and --pa
- the --password-stdin option requires --username to be set
- error: username is required
- error: password is required
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/445447c4a09d1464.json.
Report an issue: GitHub.