docker/cli · error

conflicting options: cannot specify both --password and…

Error message

conflicting options: cannot specify both --password and --password-stdin

What it means

Thrown by verifyLoginFlags when both --password (with a value other than '-') and --password-stdin are set simultaneously. These are mutually exclusive ways to supply a credential and conflict with each other.

Solutions

  1. Remove one of the two flags; keep only --password-stdin for security.
  2. If you must pass the password inline, drop --password-stdin (note the CLI warns this is insecure).

Example fix

# before
docker login -u user --password secret --password-stdin
# after
printf '%s' "$PASS" | docker login -u user --password-stdin
Defensive patterns

Strategy: validation

Validate before calling

// Reject mutually exclusive password flags up front
if passwordStdin && password != "" && password != "-" {
    return fmt.Errorf("choose either --password or --password-stdin, not both")
}

Prevention

When it happens

Trigger: Running 'docker login -u user --password secret --password-stdin' (login.go lines 75-78).

Common situations: Copy-pasting a command that included both flags; migrating from --password to --password-stdin without removing the old flag.

Related errors


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

Appendix: source

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

		DisableFlagsInUseLine: true,
	}

	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].

View on GitHub (pinned to 4f84911bfe)