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

Raised by verifyLoginFlags (cli/command/registry/login.go:80). When the password comes from stdin, the CLI cannot also prompt interactively for a username, because stdin is already consumed by the secret — so --username must be provided as a flag up front.

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., removing

View on GitHub (pinned to e9452d6e78)

Solutions

  1. Add the username flag: echo "$TOKEN" | docker login -u "$USERNAME" --password-stdin
  2. For registries with token-only auth schemes (e.g. AWS ECR uses AWS as the username, GHCR accepts your GitHub username), pass the scheme's expected username explicitly

Example fix

# before
echo "$TOKEN" | docker login --password-stdin ghcr.io

# after
echo "$TOKEN" | docker login -u my-github-user --password-stdin ghcr.io

When it happens

Trigger: docker login --password-stdin registry.example.com < token.txt without -u/--username; equivalently docker login -p - < token.txt with no username flag. Triggered purely at flag-parse time, before stdin is read.

Common situations: CI jobs that store only a token secret and forget the username variable; copy-pasted login snippets missing the -u flag; assuming the username will be taken from a previous login's config.json (it is not for --password-stdin).

Related errors


AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01). Data as JSON: /data/errors/57dfe3c122b1bdac.json. Report an issue: GitHub.