amir20/dozzle · info · ErrAuthRequired

registry requires authentication

Error message

registry requires authentication

What it means

ErrAuthRequired means the container image registry rejected an anonymous request during an update check. Dozzle has no credential store, so it cannot authenticate to private registries; instead of retrying endlessly it surfaces this sentinel so the checker can report the image as 'auth required' rather than treating it as a transient failure.

Solutions

  1. Verify the image is publicly pullable: docker manifest inspect <image> (or curl the registry v2 manifest endpoint) without credentials.
  2. If the image is private, accept the StatusAuthRequired status in the update-check result or stop watching that image; Dozzle will not check updates for it.
  3. Pull the image locally with proper docker login so the local digest exists; Dozzle can still compare against the locally available digest.
  4. If 401 is coming from Docker Hub rate limiting rather than a truly private image, wait out the rate window or use a registry mirror/proxy.
Defensive patterns

Strategy: try-catch

Validate before calling

// before relying on update checks
docker manifest inspect <image:tag> >/dev/null 2>&1 || echo 'not anonymously pullable'

Type guard

func isAuthRequired(err error) bool { return errors.Is(err, imagecheck.ErrAuthRequired) }

Try / catch

if err != nil {
  if errors.Is(err, imagecheck.ErrAuthRequired) {
    // report StatusAuthRequired; do NOT shorten TTL or retry
    result.Status = StatusAuthRequired
  } else { /* transient: retry with backoff */ }
}

Prevention

When it happens

Trigger: remoteDigest/Digest makes a manifest request without credentials and the registry answers 401 (or a token request is denied); Check and Digest propagate it, and checker.go maps it to StatusAuthRequired while deliberately NOT shortening the cache TTL (checker.go:290).

Common situations: Watching a private image (e.g. a paid or GHCR private package) whose tag cannot be read anonymously; Docker Hub rate-limit-style 401s for unauthenticated pulls; pulling images from a registry that requires a token even for manifest HEAD requests.

Understand the failure class

Related errors


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

Appendix: source

Thrown at internal/imagecheck/registry.go:31

	"github.com/rs/zerolog/log"
)

// acceptManifests lists every manifest media type we are willing to receive.
// Multi-arch images resolve to an index/manifest-list, which is the digest
// recorded in the local RepoDigests, so those come first.
var acceptManifests = strings.Join([]string{
	"application/vnd.oci.image.index.v1+json",
	"application/vnd.docker.distribution.manifest.list.v2+json",
	"application/vnd.docker.distribution.manifest.v2+json",
	"application/vnd.oci.image.manifest.v1+json",
}, ",")

var (
	// ErrAuthRequired means the registry rejected an anonymous request. Dozzle
	// has no credential store, so private images are reported rather than
	// retried.
	ErrAuthRequired = errors.New("registry requires authentication")
	// ErrNotFound means the tag no longer exists upstream.
	ErrNotFound = errors.New("image not found in registry")
	// ErrRateLimited means the registry asked us to back off.
	ErrRateLimited = errors.New("registry rate limited the request")
)

type cachedToken struct {
	token     string
	expiresAt time.Time
}

// Registry resolves the current manifest digest for an image reference using
// HEAD requests, which registries do not count against image pull rate limits.
type Registry struct {
	client *http.Client

	mu     sync.Mutex
	tokens map[string]cachedToken

View on GitHub (pinned to d9463cbe21)