amir20/dozzle · error

empty image reference

Error message

empty image reference

What it means

ParseReference rejects an empty string before doing any parsing, since an image reference must at minimum name a repository. Returning an empty image reference means the caller passed "" into the image update checker.

Solutions

  1. Check that the container/image actually has a non-empty image reference before calling ParseReference
  2. Fix the source of the empty value (container config, env var, test fixture)
  3. Guard: if ref == "" { skip the update check } instead of parsing

Example fix

// before
if err := imagecheck.Check(container.Image); err != nil { ... }
// after
if container.Image == "" {
    return nil // nothing to check
}
if err := imagecheck.Check(container.Image); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

if image == "" {
    return nil // or skip update check
}

Type guard

func hasImage(c Container) bool { return strings.TrimSpace(c.Image) != "" }

Try / catch

if err := imagecheck.Check(ref); err != nil {
    if err.Error() == "empty image reference" {
        return nil // nothing to verify
    }
    return err
}

Prevention

When it happens

Trigger: Calling ParseReference("") directly, or indirectly via Check/digestsForRepository when a container's image field is empty (image never set or stripped by a marshaling bug).

Common situations: A container record with a blank image property (e.g. a manually constructed container in tests), config where the image key was omitted, or empty string from a trimmed env/config value.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/fbd8f02371dda3ed. Report an issue: GitHub.

Appendix: source

Thrown at internal/imagecheck/reference.go:90

		return "http"
	}
	return "https"
}

// manifestURL is the v2 manifest endpoint for this reference.
func (r Reference) manifestURL() string {
	target := r.Tag
	if target == "" {
		target = r.Digest
	}
	return fmt.Sprintf("%s://%s/v2/%s/manifests/%s", r.scheme(), r.host(), r.Repository, target)
}

// ParseReference splits an image reference into its registry, repository and
// tag/digest parts, applying Docker's implicit defaults.
func ParseReference(ref string) (Reference, error) {
	if ref == "" {
		return Reference{}, fmt.Errorf("empty image reference")
	}

	remainder := ref
	var digest string
	// A digest always trails the reference and may follow a tag, as in
	// "nginx:1.25@sha256:abc...".
	if i := strings.Index(remainder, "@"); i != -1 {
		digest = remainder[i+1:]
		remainder = remainder[:i]
		if digest == "" {
			return Reference{}, fmt.Errorf("invalid image reference %q: empty digest", ref)
		}
	}

	registry := defaultRegistry
	// The first path component is a registry only when it looks like a host:
	// it contains a dot or port separator, or is localhost. Otherwise it is a
	// Docker Hub namespace such as "amir20" in "amir20/dozzle".

View on GitHub (pinned to d9463cbe21)