docker/cli · error

releases is a reserved keyword and cannot be removed

Error message

releases is a reserved keyword and cannot be removed

What it means

Returned by removeSingleSigner when the signer delegation name ('targets/' + signerName) equals the reserved releasesRoleTUFName ('targets/releases'). The releases role is system-managed and cannot be removed through the signer-remove command; removing it would destroy the release-signing delegation.

Solutions

  1. Remove only real user-defined signers, not 'releases'.
  2. If you need to alter the releases delegation keys, use the appropriate notary low-level commands or re-sign to republish it.
  3. List actual signers with 'docker trust inspect --pretty <repo>' and exclude 'releases' from removal.

Example fix

# before: docker trust signer remove releases myrepo
# after:  docker trust signer remove alice myrepo   # remove a real signer instead
Defensive patterns

Strategy: validation

Validate before calling

// Reject attempts to remove the reserved releases role
func validateRemovableSigner(name string) error {
	if data.RoleName("targets/"+name) == releasesRoleTUFName {
		return errors.New("releases is a reserved keyword and cannot be removed")
	}
	return nil
}

Prevention

When it happens

Trigger: Running 'docker trust signer remove releases <repo>' — the guard at signer_remove.go:100 rejects it immediately.

Common situations: Trying to clean up the releases role like any other signer; scripting removal of all signers including the reserved one; misunderstanding that releases is special.

Related errors


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

Appendix: source

Thrown at cmd/docker-trust/trust/signer_remove.go:101

			"Are you sure you want to continue?",
			signerName, repoName, repoName,
		)
		return prompt.Confirm(ctx, dockerCLI.In(), dockerCLI.Out(), message)
	}
	return false, nil
}

// removeSingleSigner attempts to remove a single signer and returns whether signer removal happened.
// The signer not being removed doesn't necessarily raise an error e.g. user choosing "No" when prompted for confirmation.
func removeSingleSigner(ctx context.Context, dockerCLI command.Cli, repoName, signerName string, forceYes bool) (bool, error) {
	imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, authResolver(dockerCLI), repoName)
	if err != nil {
		return false, err
	}

	signerDelegation := data.RoleName("targets/" + signerName)
	if signerDelegation == releasesRoleTUFName {
		return false, errors.New("releases is a reserved keyword and cannot be removed")
	}
	notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull)
	if err != nil {
		return false, trust.NotaryError(imgRefAndAuth.Reference().Name(), err)
	}
	delegationRoles, err := notaryRepo.GetDelegationRoles()
	if err != nil {
		return false, fmt.Errorf("error retrieving signers for %s: %w", repoName, err)
	}
	var role data.Role
	for _, delRole := range delegationRoles {
		if delRole.Name == signerDelegation {
			role = delRole
			break
		}
	}
	if role.Name == "" {
		return false, fmt.Errorf("no signer %s for repository %s", signerName, repoName)

View on GitHub (pinned to 4f84911bfe)