goharbor/harbor · error

preheating is failed

Error message

preheating is failed

What it means

The P2P preheat job's status check found that the provider (Dragonfly, Kraken, etc.) already reported the preheat request as failed in the initial response — for these drivers the first status is final, so the job is immediately marked failed via preheatJobRunningError. It indicates the provider-side distribution task failed, not that Harbor could not talk to the provider (that produces a different send error).

Source

Thrown at src/pkg/p2p/preheat/job.go:155

		return nil
	}

	// Then send the preheat requests to the target provider.
	st, err := d.Preheat(pi)
	if err != nil {
		return preheatJobRunningError(err)
	}

	myLogger.Info("Sending preheat request is successfully done")

	// For some of the drivers, e.g: Kraken, the returned status of preheating request contains the
	// final status info. No need to loop check the status.
	switch st.Status {
	case provider.PreheatingStatusSuccess:
		myLogger.Info("Preheating is completed")
		return nil
	case provider.PreheatingStatusFail:
		err = errors.New("preheating is failed")
		return preheatJobRunningError(err)
	case provider.PreheatingStatusPending,
		provider.PreheatingStatusRunning:
	// do nothing
	default:
		// in case
		err = errors.Errorf("unknown status '%s' returned by the preheat provider %s-%s:%s", st.Status, p.Vendor, p.Name, p.Endpoint)
		return preheatJobRunningError(err)
	}

	if shouldStop() {
		return nil
	}

	myLogger.Info("Start to loop check the preheating status until it's success or timeout(30m)")
	// If process is not completed, loop check the status until it's ready.
	tk := time.NewTicker(checkInterval)
	defer tk.Stop()

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Check the provider's own logs/scheduler for the failed task correlated with the execution ID.
  2. Verify instance connectivity and health from Harbor core (GET /api/v2.0/p2p/preheat/instances, then ping the provider endpoint) and that the provider cluster is healthy.
  3. Confirm the artifact is pullable: correct repo/tag in the policy filters, image exists, and instance auth (auth_info) is valid for pulling.
  4. Fix the root cause then re-run: POST /api/v2.0/projects/{project}/preheat/policies/{policy_id}/executions to create a new execution.
Defensive patterns

Strategy: retry

Validate before calling

// Before triggering preheat, confirm the provider side is up
// GET /api/v2.0/p2p/preheat/instances -> check the instance; then from core:
resp, err := http.Get(instance.Endpoint + "/health") // provider-appropriate health route
if err != nil || resp.StatusCode >= 500 { fail("provider unhealthy — fix before preheating") }

Try / catch

In job/execution monitoring, treat this as a terminal-fail status: inspect provider logs, fix the root cause (cluster health, image pullability, auth), then create a NEW execution (POST .../preheat/policies/{id}/executions) rather than restarting the failed one unchanged.

Prevention

When it happens

Trigger: Executing a preheat policy (manual trigger POST .../preheat/policies/{id}/executions, scheduled trigger, or event-based) against an instance whose API accepts the request but returns status=fail — e.g. Dragonfly scheduler cannot pull the image, seed peers unavailable, or the provider rejects the task.

Common situations: Dragonfly/Kraken cluster partially down (seed peers offline); image not pullable by the provider (private repo + missing/incorrect instance auth, image not yet pushed/PUSH missing); version incompatibility between Harbor and the distribution plugin; resource exhaustion on the provider returning fail fast.

Related errors


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/8afa5cbc22c6f755. Report an issue: GitHub.