docker/cli · error
key name " " must start with lowercase alphanumeric…
Error message
key name "%s" must start with lowercase alphanumeric characters and can include "-" or "_" after the first character
What it means
In loadPrivKey (key_load.go:46-50), the --name flag value fails the validKeyName regex (same ^[a-z0-9][a-z0-9_\-]*$ pattern shared with key_generate). The default --name is 'signer' (key_load.go:42), so this only fires when the user explicitly passes a non-conformant --name.
Solutions
- Use a conformant --name: lowercase alphanumerics with optional '-'/'_', e.g. --name frontend-team.
- Omit --name to use the default 'signer'.
- Strip/normalize the value to lowercase and replace disallowed chars with '-' or '_'.
Example fix
# before docker trust key load priv.key --name 'CI Signer' # after docker trust key load priv.key --name ci-signer
Defensive patterns
Strategy: validation
Validate before calling
// Reuse the shared regex to validate --name before loading.
func validateLoadKeyName(name string) error {
if name != "" && !validKeyName(name) {
return fmt.Errorf("key name %q must start with lowercase alphanumeric and may contain '-' or '_'", name)
}
return nil
} Try / catch
if options.keyName != "" && !validKeyName(options.keyName) {
return fmt.Errorf("key name %q must start with lowercase alphanumeric ...", options.keyName)
} Prevention
- Use kebab-case lowercase names for --name.
- Omit --name to default to 'signer' when the role name does not matter.
- Validate names in automation scripts before invoking the command.
When it happens
Trigger: Running 'docker trust key load <keyfile> --name <NAME>' where NAME contains uppercase, spaces, dots, leading hyphen/underscore, '@', or other punctuation, or is empty after the flag.
Common situations: User passes a display name like 'Frontend Team' or 'CI'; uses an email 'ci@corp'; copies a role name with uppercase; passes '--name=' (empty).
Related errors
- key name " " must start with lowercase alphanumeric…
- public key path does not exist
- public key file already exists
- refusing to load key from
- provided file is not a supported private key - to add a…
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/9c9625e822cd90ea.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/docker-trust/trust/key_load.go:49
var options keyLoadOptions
cmd := &cobra.Command{
Use: "load [OPTIONS] KEYFILE",
Short: "Load a private key file for signing",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return loadPrivKey(dockerCLI, args[0], options)
},
DisableFlagsInUseLine: true,
}
flags := cmd.Flags()
flags.StringVar(&options.keyName, "name", "signer", "Name for the loaded key")
return cmd
}
func loadPrivKey(streams command.Streams, keyPath string, options keyLoadOptions) error {
// validate the key name if provided
if options.keyName != "" && !validKeyName(options.keyName) {
return fmt.Errorf("key name \"%s\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character", options.keyName)
}
trustDir := trust.GetTrustDirectory()
keyFileStore, err := storage.NewPrivateKeyFileStorage(trustDir, notary.KeyExtension)
if err != nil {
return err
}
privKeyImporters := []trustmanager.Importer{keyFileStore}
_, _ = fmt.Fprintf(streams.Out(), "Loading key from \"%s\"...\n", keyPath)
// Always use a fresh passphrase retriever for each import
passRet := trust.GetPassphraseRetriever(streams.In(), streams.Out())
keyBytes, err := getPrivKeyBytesFromPath(keyPath)
if err != nil {
return fmt.Errorf("refusing to load key from %s: %w", keyPath, err)
}
if err := loadPrivKeyBytesToStore(keyBytes, privKeyImporters, keyPath, options.keyName, passRet); err != nil {
return fmt.Errorf("error importing key from %s: %w", keyPath, err)View on GitHub (pinned to 4f84911bfe)