goharbor/harbor · error

check scan report timeout

Error message

check scan report timeout

What it means

Produced in the scan job's report-polling goroutines when the per-mime-type check loop exceeds checkTimeout. The goroutine polls fetchScanReportFromScanner at the scanner-advised RetryAfter intervals; if the report never becomes ready before time.After(checkTimeout) fires, the error is recorded for that mime type.

Source

Thrown at src/pkg/scan/job.go:267

					rawReport, err := fetchScanReportFromScanner(client, resp.ID, m, reportURLParameter)
					if err != nil {
						// Not ready yet
						if notReadyErr, ok := err.(*v1.ReportNotReadyError); ok {
							// Reset to the new check interval
							tm.Reset(time.Duration(notReadyErr.RetryAfter) * time.Second)
							myLogger.Infof("Report with mime type %s is not ready yet, retry after %d seconds", m, notReadyErr.RetryAfter)
							continue
						}
						errs[i] = errors.Wrap(err, fmt.Sprintf("scan job: fetch scan report, mimetype %v", m))
						return
					}
					rawReports[i] = rawReport
					return
				case <-ctx.SystemContext().Done():
					// Terminated by system
					return
				case <-time.After(checkTimeout):
					errs[i] = errors.New("check scan report timeout")
					return
				}
			}
		}(i, mimeType)
	}

	// Wait for all the retrieving routines are completed
	wg.Wait()

	if shouldStop() {
		return nil
	}

	// Merge errors
	for _, e := range errs {
		if e != nil {
			if err != nil {
				err = errors.Wrap(e, err.Error())

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Check scanner adapter health and load; scale the adapter or reduce concurrent scans
  2. Increase the scan check-timeout configuration in Harbor (scanner adapter and job settings) to fit large-image scan durations
  3. Rescan the specific artifact once the adapter is idle; on-demand scans usually succeed where scan_all timed out
  4. Verify network latency/MTU between core and scanner adapter pods

Example fix

// before
// default checkTimeout too short for large images
checkTimeout = 30 * time.Minute

// after
checkTimeout = 2 * time.Hour // sized for scan_all on large registries
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight the adapter before launching bulk scans
resp, err := scannerClient.GetMetadata()
if err != nil || resp == nil {
    return fmt.Errorf("scanner adapter not ready: %v", err)
}

Try / catch

if err := runScan(artifact); err != nil {
    if strings.Contains(err.Error(), "check scan report timeout") {
        // transient: adapter overloaded; backoff and rescan this artifact later
        time.Sleep(5 * time.Minute)
        return runScan(artifact)
    }
    return err
}

Prevention

When it happens

Trigger: Scanner adapter consistently answering ReportNotReady for longer than the hard deadline; scanner overloaded (scan_all on a large registry); slow network between Harbor core and the adapter; adapter's RetryAfter values repeatedly resetting the timer past the ceiling.

Common situations: Trivy or other adapters queueing behind big image scans; resource-starved scanner pods; scanning very large images where the adapter takes longer than the configured check timeout; retries after adapter restarts losing scan state.

Understand the failure class

Related errors


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