docker/cli · error

no tag specified

Error message

no tag specified

What it means

Returned by createTarget when tag is empty — a defensive guard asserting that a target name is required to look up the signed manifest hash and size. In practice validateTag usually catches the missing tag first; this error surfaces when createTarget is reached with an empty tag (e.g. via a code path that bypasses validateTag).

Solutions

  1. Provide an explicit tag: 'docker trust sign repo/image:tag'.
  2. If scripting, assert the reference contains a tag before invoking docker trust sign.
  3. Check that the image name string is not truncated or missing the ':tag' suffix.

Example fix

# before: docker trust sign myrepo/img      # no tag
# after:  docker trust sign myrepo/img:v1
Defensive patterns

Strategy: validation

Validate before calling

// Assert a non-empty tag before creating a target
func ensureTag(tag string) error {
	if tag == "" { return errors.New("no tag specified") }
	return nil
}

Prevention

When it happens

Trigger: Calling createTarget(notaryRepo, '') directly, or runSignImage reaching createTarget with an empty tag due to a reference that is neither tagged nor digested.

Common situations: Signing a bare repository name with no tag or digest: 'docker trust sign repo/image'; a reference parsing edge case that yields no tag.

Related errors


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

Appendix: source

Thrown at cmd/docker-trust/trust/sign.go:155

	if tag == "" {
		if imgRefAndAuth.Digest() != "" {
			return errors.New("cannot use a digest reference for IMAGE:TAG")
		}
		return fmt.Errorf("no tag specified for %s", imgRefAndAuth.Name())
	}
	return nil
}

func checkLocalImageExistence(ctx context.Context, apiClient client.APIClient, imageName string) error {
	_, err := apiClient.ImageInspect(ctx, imageName)
	return err
}

func createTarget(notaryRepo notaryclient.Repository, tag string) (notaryclient.Target, error) {
	target := &notaryclient.Target{}
	var err error
	if tag == "" {
		return *target, errors.New("no tag specified")
	}
	target.Name = tag
	target.Hashes, target.Length, err = getSignedManifestHashAndSize(notaryRepo, tag)
	return *target, err
}

func getSignedManifestHashAndSize(notaryRepo notaryclient.Repository, tag string) (data.Hashes, int64, error) {
	targets, err := notaryRepo.GetAllTargetMetadataByName(tag)
	if err != nil {
		return nil, 0, err
	}
	return getReleasedTargetHashAndSize(targets, tag)
}

func getReleasedTargetHashAndSize(targets []notaryclient.TargetSignedStruct, tag string) (data.Hashes, int64, error) {
	for _, tgt := range targets {
		if isReleasedTarget(tgt.Role.Name) {
			return tgt.Target.Hashes, tgt.Target.Length, nil

View on GitHub (pinned to 4f84911bfe)