{"id":"f1b15b87b44c5ba0","repo":"docker/cli","slug":"username-is-empty","errorCode":null,"errorMessage":"username is empty","messagePattern":"username is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/registry/login.go","lineNumber":84,"sourceCode":"\tflags.BoolVar(&opts.passwordStdin, \"password-stdin\", false, \"Take the Password or Personal Access Token (PAT) from stdin\")\n\n\treturn cmd\n}\n\n// verifyLoginFlags validates flags set on the command.\n//\n// TODO(thaJeztah); combine with verifyLoginOptions, but this requires rewrites of many tests.\nfunc verifyLoginFlags(flags *pflag.FlagSet, opts loginOptions) error {\n\tif flags.Changed(\"password-stdin\") || opts.password == \"-\" {\n\t\tif flags.Changed(\"password\") && opts.password != \"-\" {\n\t\t\treturn errors.New(\"conflicting options: cannot specify both --password and --password-stdin\")\n\t\t}\n\t\tif !flags.Changed(\"username\") {\n\t\t\treturn errors.New(\"the --password-stdin option requires --username to be set\")\n\t\t}\n\t}\n\tif flags.Changed(\"username\") && opts.user == \"\" {\n\t\treturn errors.New(\"username is empty\")\n\t}\n\tif flags.Changed(\"password\") && opts.password == \"\" {\n\t\treturn errors.New(\"password is empty\")\n\t}\n\treturn nil\n}\n\n// readSecretFromStdin reads the secret from r and returns it as a string.\n// It trims terminal line-endings (LF, CRLF, or CR), which may be added when\n// inputting interactively or piping input. The value is otherwise treated as\n// opaque, preserving any other whitespace, including newlines, per [NIST SP 800-63B §5.1.1.2].\n// Note that trimming whitespace may still happen elsewhere (see [NIST SP 800-63B (revision 4) §3.1.1.2]);\n//\n// > Verifiers **MAY** make limited allowances for mistyping (e.g., removing\n// > leading and trailing whitespace characters before verification, allowing\n// > the verification of passwords with differing cases for the leading character)\n//\n// [NIST SP 800-63B §5.1.1.2]: https://pages.nist.gov/800-63-3/sp800-63b.html#memsecretver","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/docker/cli/blob/e9452d6e785f6e365712b9d71bd7517591773c86/cli/command/registry/login.go#L66-L102","documentation":"Raised by verifyLoginFlags (cli/command/registry/login.go:84) when the --username flag was explicitly set on the command line but its value is an empty string. Explicitly passing an empty username is treated as a mistake rather than a request to prompt.","triggerScenarios":"docker login -u '' registry.example.com; docker login --username=\"\" — the flag is marked Changed by pflag but opts.user is \"\". Typically the result of an unset shell variable: docker login -u \"$USER_VAR\" where USER_VAR is empty.","commonSituations":"CI secrets/variables that are defined but empty (misnamed variable, wrong scope, unexported env var); templating systems rendering an empty value into the -u flag; quoting bugs where the intended value lands in the next argument.","solutions":["Verify the shell/CI variable actually has a value (echo its length or use ${VAR:?} to fail fast: docker login -u \"${REGISTRY_USER:?}\" ...)","If you want the interactive username prompt, omit the -u flag entirely instead of passing an empty value","Check CI secret scoping — org/repo/environment-level secrets can be silently empty in forks or unmatched environments"],"exampleFix":"# before (REGISTRY_USER unset)\ndocker login -u \"$REGISTRY_USER\" --password-stdin registry.example.com\n\n# after (fail fast with a clear message if unset)\ndocker login -u \"${REGISTRY_USER:?REGISTRY_USER is not set}\" --password-stdin registry.example.com","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["docker-cli","registry","authentication","flag-validation","environment-variables"],"analyzedSha":"e9452d6e785f6e365712b9d71bd7517591773c86","analyzedAt":"2026-08-01T07:09:22.474Z","schemaVersion":2}