{"record":{"id":"09716f5171b067b0","repo":"docker/cli","slug":"could-not-add-signer-to-repo-s-w","errorCode":null,"errorMessage":"could not add signer to repo: %s: %w","messagePattern":"could not add signer to repo: (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/docker-trust/trust/sign.go","lineNumber":214,"sourceCode":"\nfunc initNotaryRepoWithSigners(notaryRepo notaryclient.Repository, newSigner data.RoleName) error {\n\trootKey, err := getOrGenerateNotaryKey(notaryRepo, data.CanonicalRootRole)\n\tif err != nil {\n\t\treturn err\n\t}\n\trootKeyID := rootKey.ID()\n\n\t// Initialize the notary repository with a remotely managed snapshot key\n\tif err := notaryRepo.Initialize([]string{rootKeyID}, data.CanonicalSnapshotRole); err != nil {\n\t\treturn err\n\t}\n\n\tsignerKey, err := getOrGenerateNotaryKey(notaryRepo, newSigner)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := addStagedSigner(notaryRepo, newSigner, []data.PublicKey{signerKey}); err != nil {\n\t\treturn fmt.Errorf(\"could not add signer to repo: %s: %w\", strings.TrimPrefix(newSigner.String(), \"targets/\"), err)\n\t}\n\n\treturn notaryRepo.Publish()\n}\n\n// generates an ECDSA key without a GUN for the specified role\nfunc getOrGenerateNotaryKey(notaryRepo notaryclient.Repository, role data.RoleName) (data.PublicKey, error) {\n\t// use the signer name in the PEM headers if this is a delegation key\n\tif data.IsDelegation(role) {\n\t\trole = data.RoleName(notaryRoleToSigner(role))\n\t}\n\tkeys := notaryRepo.GetCryptoService().ListKeys(role)\n\tvar err error\n\tvar key data.PublicKey\n\t// always select the first key by ID\n\tif len(keys) > 0 {\n\t\tsort.Strings(keys)\n\t\tkeyID := keys[0]","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cmd/docker-trust/trust/sign.go#L196-L232","documentation":"Returned during `docker trust sign` inside initNotaryRepoWithSigners() when a brand-new notary repository is being initialized and addStagedSigner() fails to create the targets/<username> delegation role (AddDelegationRoleAndKeys / AddDelegationPaths / ReleasesRole setup). %s is the signer role name (username), %w is the notary staging error. This is part of first-time repo bootstrap, not an add-signer flow.","triggerScenarios":"First `docker trust sign` against a repo where ListTargets() returns ErrRepoNotInitialized/ErrRepositoryNotExist, initNotaryRepoWithSigners runs, getOrGenerateNotaryKey succeeds, but addStagedSigner fails — typically due to crypto-service key creation failure or invalid delegation metadata staging.","commonSituations":"Corrupt or permission-restricted ~/.docker/trust keystore; running as a user without write access to the trust directory; key generation entropy or hardware-backed key issues; username containing characters not valid in a TUF role name.","solutions":["Check permissions and integrity of ~/.docker/trust (read/write access for the current user).","Avoid usernames with characters that break TUF role path construction; use a simple lowercase username.","Retry after clearing any partial/locked trust metadata for that repo.","Inspect the wrapped %w for the crypto-service or staging error to pinpoint key vs metadata failure."],"exampleFix":"// before\n$ docker trust sign registry.example.com/newrepo:v1\nError: could not add signer to repo: alice: ...\n\n// after — fix trust keystore permissions then re-initialize\n$ chmod -R u+rwX ~/.docker/trust\n$ docker trust sign registry.example.com/newrepo:v1","handlingStrategy":"validation","validationCode":"// Before first sign, ensure the trust keystore is writable and the username is role-safe\nfunc preSignBootstrap(repo string) error {\n    info, err := os.Stat(filepath.Join(homedir.Dir(), \".docker\", \"trust\"))\n    if err != nil { return err }\n    if !info.IsDir() { return errors.New(\"~/.docker/trust is not a directory\") }\n    if os.Geteuid() == 0 { return errors.New(\"do not sign as root without a trust keystore owner\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Bootstrap init errors are usually permanent for the session; surface and stop\nout, err := exec.CommandContext(ctx, \"docker\", \"trust\", \"sign\", ref).CombinedOutput()\nif err != nil && strings.Contains(string(out), \"could not add signer to repo\") {\n    return fmt.Errorf(\"trust bootstrap failed, check ~/.docker/trust perms: %s\", out)\n}","preventionTips":["Use a lowercase-alphanumeric username so the derived delegation role is valid.","Ensure write access to ~/.docker/trust before first sign.","Don't share the trust keystore across concurrent processes."],"tags":["docker","trust","notary","delegation","keystore"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}