{"record":{"id":"f902c51dce030f4f","repo":"docker/cli","slug":"failed-to-add-signer-to-s","errorCode":null,"errorMessage":"failed to add signer to: %s","messagePattern":"failed to add signer to: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/docker-trust/trust/signer_add.go","lineNumber":77,"sourceCode":"\tif options.keys.Len() == 0 {\n\t\treturn errors.New(\"path to a public key must be provided using the `--key` flag\")\n\t}\n\tsignerPubKeys, err := ingestPublicKeys(options.keys.GetSlice())\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar errRepos []string\n\tfor _, repoName := range options.repos {\n\t\t_, _ = fmt.Fprintf(dockerCLI.Out(), \"Adding signer \\\"%s\\\" to %s...\\n\", signerName, repoName)\n\t\tif err := addSignerToRepo(ctx, dockerCLI, signerName, repoName, signerPubKeys); err != nil {\n\t\t\t_, _ = fmt.Fprintln(dockerCLI.Err(), err.Error()+\"\\n\")\n\t\t\terrRepos = append(errRepos, repoName)\n\t\t} else {\n\t\t\t_, _ = fmt.Fprintf(dockerCLI.Out(), \"Successfully added signer: %s to %s\\n\\n\", signerName, repoName)\n\t\t}\n\t}\n\tif len(errRepos) > 0 {\n\t\treturn fmt.Errorf(\"failed to add signer to: %s\", strings.Join(errRepos, \", \"))\n\t}\n\treturn nil\n}\n\nfunc addSignerToRepo(ctx context.Context, dockerCLI command.Cli, signerName string, repoName string, signerPubKeys []data.PublicKey) error {\n\timgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, authResolver(dockerCLI), repoName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnotaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull)\n\tif err != nil {\n\t\treturn trust.NotaryError(imgRefAndAuth.Reference().Name(), err)\n\t}\n\n\tif _, err = notaryRepo.ListTargets(); err != nil {\n\t\tswitch err.(type) {\n\t\tcase client.ErrRepoNotInitialized, client.ErrRepositoryNotExist:","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cmd/docker-trust/trust/signer_add.go#L59-L95","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n$ docker trust signer add alice reg1.io/app reg2.io/app --key alice.pub\nAdding signer \"alice\" to reg2.io/app...\n<per-repo error>\nError: failed to add signer to: reg2.io/app\n\n// after — fix reg2 auth/init then retry just that repo\n$ docker login reg2.io\n$ docker trust signer add alice reg2.io/app --key alice.pub","handlingStrategy":"try-catch","validationCode":"// Pre-check each repo is reachable and push-authed before bulk signer add\nfunc preCheckRepos(repos []string) ([]string, error) {\n    var ok []string\n    for _, r := range repos {\n        if out, err := exec.Command(\"docker\", \"trust\", \"inspect\", r).CombinedOutput(); err != nil {\n            log.Printf(\"skip %s: %s\", r, out); continue\n        }\n        ok = append(ok, r)\n    }\n    if len(ok) == 0 { return nil, errors.New(\"no reachable repos\") }\n    return ok, nil\n}","typeGuard":null,"tryCatchPattern":"// Bulk add: parse the aggregate failure list and retry the survivors individually\nout, err := exec.CommandContext(ctx, \"docker\", \"trust\", \"signer\", \"add\", name).CombinedOutput() // + repos, --key\nif err != nil {\n    // out already contains per-repo errors on stderr; surface them\n    return fmt.Errorf(\"partial signer add failed:\\n%s\", out)\n}","preventionTips":["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."],"tags":["docker","trust","aggregate","notary","registry"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}