containerd/containerd · error

failed to get status: %w

Error message

failed to get status: %w

What it means

dockerPusher.push calls p.tracker.GetStatus(ref) to learn about prior push attempts. If GetStatus fails with any error other than NotFound (i.e. the tracker itself is broken or its backing store failed), the pusher cannot safely proceed and wraps the tracker error as "failed to get status". The original tracker error is preserved via %w for errors.Is/As inspection.

Source

Thrown at core/remotes/docker/pusher.go:104

		ctx = context.WithValue(ctx, warningSourceKey{}, WarningSource{
			Desc:   &desc,
			Digest: &desc.Digest,
		})
	}
	status, err := p.tracker.GetStatus(ref)
	if err == nil {
		if status.Committed && status.Offset == status.Total {
			return nil, fmt.Errorf("ref %v: %w", ref, errdefs.ErrAlreadyExists)
		}
		if unavailableOnFail && status.ErrClosed == nil {
			// Another push of this ref is happening elsewhere. The rest of function
			// will continue only when `errdefs.IsNotFound(err) == true` (i.e. there
			// is no actively-tracked ref already).
			return nil, fmt.Errorf("push is on-going: %w", errdefs.ErrUnavailable)
		}
		// TODO: Handle incomplete status
	} else if !errdefs.IsNotFound(err) {
		return nil, fmt.Errorf("failed to get status: %w", err)
	}

	hosts := p.filterHosts(HostCapabilityPush)
	if len(hosts) == 0 {
		return nil, fmt.Errorf("no push hosts: %w", errdefs.ErrNotFound)
	}

	var (
		isManifest bool
		existCheck []string
		host       = hosts[0]
	)

	if images.IsManifestType(desc.MediaType) || images.IsIndexType(desc.MediaType) {
		isManifest = true
		existCheck = getManifestPath(p.object, desc.Digest)
	} else {
		existCheck = []string{"blobs", desc.Digest.String()}

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Inspect the wrapped error (errors.Unwrap / %v of err) to find the real tracker failure
  2. Verify the StatusTracker backend (DB, redis, file) is reachable and has correct permissions
  3. Fall back to the default in-memory InFlightTracker if a custom tracker misbehaves
  4. Retry once the tracker backend recovers — this is an infrastructure, not a content, problem

Example fix

// before
tracker := NewRedisStatusTracker(badAddr)
// after
if err := tracker.Ping(); err != nil { log.Fatalf("tracker unavailable: %v", err) }
tracker := NewRedisStatusTracker(addr)
Defensive patterns

Strategy: try-catch

Validate before calling

// verify tracker backend reachable before push
if err := healthCheckTracker(tracker); err != nil {
    return fmt.Errorf("tracker not ready: %w", err)
}

Type guard

null

Try / catch

w, err := pusher.Writer(ctx, opts...)
if err != nil {
    var inner error
    if strings.Contains(err.Error(), "failed to get status") {
        errors.As(err, &inner) // inspect tracker root cause
        return fmt.Errorf("tracker failure, aborting push: %v", inner)
    }
    return err
}

Prevention

When it happens

Trigger: GetStatus returning a non-NotFound error: custom StatusTracker backend (DB/redis) unreachable, corrupted status file in the external tracker, lock contention errors from a StatusTrackLocker implementation, or disk I/O errors in persistent trackers.

Common situations: Misconfigured external status-tracker storage; network partitions to a remote tracker service; file permission problems on persistent tracker state; buggy third-party StatusTracker plugins.

Related errors


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/308cccbec47e1ae2. Report an issue: GitHub.