docker/cli · error
the --password-stdin option requires --username to be set
Error message
the --password-stdin option requires --username to be set
What it means
Thrown by verifyLoginFlags when --password-stdin is set (or --password is '-') but --username was not provided. Reading the password from stdin is non-interactive, so a username must be supplied explicitly via the flag.
Solutions
- Add the --username (-u) flag.
- Use the full form: 'printf %s "$TOKEN" | docker login -u <user> --password-stdin'.
Example fix
# before printf '%s' "$TOKEN" | docker login --password-stdin # after printf '%s' "$TOKEN" | docker login -u myuser --password-stdin
Defensive patterns
Strategy: validation
Validate before calling
// Require a username whenever stdin password mode is used
if (passwordStdin || password == "-") && strings.TrimSpace(username) == "" {
return fmt.Errorf("--password-stdin requires --username")
} Prevention
- Always include -u when using --password-stdin.
- Template CI commands with a mandatory username variable.
- Fail fast in scripts if the username variable is empty.
When it happens
Trigger: Running 'echo $TOKEN | docker login --password-stdin' without -u (login.go lines 75, 79-81).
Common situations: Forgetting the -u flag in CI scripts; assuming a stored username will be reused when piping a password.
Related errors
- conflicting options: cannot specify both --password and…
- username is empty
- password is empty
- error: username is required
- error: password is required
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/57dfe3c122b1bdac.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/registry/login.go:80
flags := cmd.Flags()
flags.StringVarP(&opts.user, "username", "u", "", "Username")
flags.StringVarP(&opts.password, "password", "p", "", `Password or Personal Access Token (PAT), or "-" to read from stdin`)
flags.BoolVar(&opts.passwordStdin, "password-stdin", false, "Take the Password or Personal Access Token (PAT) from stdin")
return cmd
}
// 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., removingView on GitHub (pinned to 4f84911bfe)