docker/cli · error

path to a public key must be provided using the `--key` flag

Error message

path to a public key must be provided using the `--key` flag

What it means

Returned by addSigner when options.keys is empty — the user invoked 'docker trust signer add' without any --key flag. Adding a signer requires at least one public key to attach to the delegation role, so a missing key is rejected before contacting the Notary server.

Solutions

  1. Provide at least one --key flag pointing to the signer's public key PEM file.
  2. Generate the public key with 'docker trust key generate' (or notary key generate) if you do not have one yet.
  3. Double-check flag spelling: it is --key (not --keys or --pubkey).

Example fix

# before: docker trust signer add alice myrepo
# after:  docker trust signer add alice --key alice.pub myrepo
Defensive patterns

Strategy: validation

Validate before calling

// Ensure at least one --key is provided before adding a signer
func validateSignerKeys(keys []string) error {
	if len(keys) == 0 {
		return errors.New("path to a public key must be provided using the --key flag")
	}
	return nil
}

Prevention

When it happens

Trigger: Running 'docker trust signer add alice myrepo' with no '--key <pubkeyfile>' arguments; the flag count check at signer_add.go:59 fails.

Common situations: Forgetting the --key flag; passing the key as a positional arg instead of via --key; assuming a default key is used.

Related errors


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

Appendix: source

Thrown at cmd/docker-trust/trust/signer_add.go:60

	flags := cmd.Flags()
	options.keys = opts.NewListOpts(nil)
	flags.Var(&options.keys, "key", "Path to the signer's public key file")
	return cmd
}

var validSignerName = lazyregexp.New(`^[a-z0-9][a-z0-9\_\-]*$`).MatchString

func addSigner(ctx context.Context, dockerCLI command.Cli, options signerAddOptions) error {
	signerName := options.signer
	if !validSignerName(signerName) {
		return fmt.Errorf("signer name \"%s\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character", signerName)
	}
	if signerName == "releases" {
		return errors.New("releases is a reserved keyword, use a different signer name")
	}

	if options.keys.Len() == 0 {
		return errors.New("path to a public key must be provided using the `--key` flag")
	}
	signerPubKeys, err := ingestPublicKeys(options.keys.GetSlice())
	if err != nil {
		return err
	}
	var errRepos []string
	for _, repoName := range options.repos {
		_, _ = fmt.Fprintf(dockerCLI.Out(), "Adding signer \"%s\" to %s...\n", signerName, repoName)
		if err := addSignerToRepo(ctx, dockerCLI, signerName, repoName, signerPubKeys); err != nil {
			_, _ = fmt.Fprintln(dockerCLI.Err(), err.Error()+"\n")
			errRepos = append(errRepos, repoName)
		} else {
			_, _ = fmt.Fprintf(dockerCLI.Out(), "Successfully added signer: %s to %s\n\n", signerName, repoName)
		}
	}
	if len(errRepos) > 0 {
		return fmt.Errorf("failed to add signer to: %s", strings.Join(errRepos, ", "))
	}

View on GitHub (pinned to 4f84911bfe)