docker/cli · error
failed to add signer to
Error message
failed to add signer to: %s
What it means
Returned by `docker trust signer add` (addSigner) as an aggregate error when one or more of the listed REPOSITORY targets failed during addSignerToRepo(). The function iterates all repos, collects failures into errRepos, prints each underlying error to stderr, and returns this summary listing the failing repositories joined by ', '. %s is that comma-joined list.
Solutions
- Read the per-repo errors printed to stderr just before this summary — they contain the real cause for each repo.
- Retry signer add only against the failing repositories once their individual issues (auth, init) are resolved.
- Verify push credentials and notary reachability for each registry host involved.
- Confirm the public key file is valid (see ingestPublicKeys errors) so all repos get a fair attempt.
Example fix
// before $ docker trust signer add alice reg1.io/app reg2.io/app --key alice.pub Adding signer "alice" to reg2.io/app... <per-repo error> Error: failed to add signer to: reg2.io/app // after — fix reg2 auth/init then retry just that repo $ docker login reg2.io $ docker trust signer add alice reg2.io/app --key alice.pub
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check each repo is reachable and push-authed before bulk signer add
func preCheckRepos(repos []string) ([]string, error) {
var ok []string
for _, r := range repos {
if out, err := exec.Command("docker", "trust", "inspect", r).CombinedOutput(); err != nil {
log.Printf("skip %s: %s", r, out); continue
}
ok = append(ok, r)
}
if len(ok) == 0 { return nil, errors.New("no reachable repos") }
return ok, nil
} Try / catch
// Bulk add: parse the aggregate failure list and retry the survivors individually
out, err := exec.CommandContext(ctx, "docker", "trust", "signer", "add", name).CombinedOutput() // + repos, --key
if err != nil {
// out already contains per-repo errors on stderr; surface them
return fmt.Errorf("partial signer add failed:\n%s", out)
} Prevention
- Add signers to one repo at a time in critical pipelines to get precise errors.
- Confirm each registry host is reachable and push-authed before bulk ops.
- Parse stderr lines for per-repo causes rather than relying on the summary alone.
When it happens
Trigger: Running `docker trust signer add <name> <repo1> <repo2> <repo3> --key k.pub` where at least one repo fails (notary init error, publish error, network, auth). Each individual repo error is printed first; this message names which repos failed overall.
Common situations: Bulk-adding a signer across many repos where some repos are on a different registry, some lack push perms, or some are uninitialized and init fails.
Related errors
- could not remove signature for
- error removing signer from
- failed to sign
- could not add signer to repo
- could not add signer to repo
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/f902c51dce030f4f.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/docker-trust/trust/signer_add.go:77
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, ", "))
}
return nil
}
func addSignerToRepo(ctx context.Context, dockerCLI command.Cli, signerName string, repoName string, signerPubKeys []data.PublicKey) error {
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, authResolver(dockerCLI), repoName)
if err != nil {
return err
}
notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull)
if err != nil {
return trust.NotaryError(imgRefAndAuth.Reference().Name(), err)
}
if _, err = notaryRepo.ListTargets(); err != nil {
switch err.(type) {
case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist:View on GitHub (pinned to 4f84911bfe)