abiosoft/colima · error

error resolving download URL '%s': %w

Error message

error resolving download URL '%s': %w

What it means

The pre-flight HEAD via GetFinalURL failed, so the actual GET never starts. The wrapped error is either *NetworkError (DNS failure, connection refused/timeout — errors.go renders friendly DNS/timeout text) or *HTTPStatusError (status >= 400 after following up to 10 redirects, e.g. 404 for a removed asset, 403/429 rate-limiting, or 405 from servers that reject HEAD).

Source

Thrown at util/downloader/native.go:41

	}

	// get existing file size for resume
	var existingSize int64
	if stat, err := os.Stat(destPath); err == nil {
		existingSize = stat.Size()
	}

	// create HTTP client
	client := NewHTTPClient()

	// use a long timeout for large files (2 hours)
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Hour)
	defer cancel()

	// get final URL (follows redirects)
	finalURL, err := client.GetFinalURL(ctx, r.URL)
	if err != nil {
		return fmt.Errorf("error resolving download URL '%s': %w", r.URL, err)
	}

	// download the file
	result, err := client.Download(ctx, DownloadOptions{
		URL:            finalURL,
		DestPath:       destPath,
		ExpectedETag:   resumeInfo.ETag,
		ResumeFromByte: existingSize,
		ShowProgress:   true,
	})
	if err != nil {
		// save resume info for next attempt if we have ETag
		if result != nil && result.ETag != "" {
			d.saveResumeInfo(r.URL, result.ETag, existingSize)
		}
		return fmt.Errorf("error downloading '%s': %w", path.Base(r.URL), err)
	}

View on GitHub (pinned to c3a5f9184d)

Solutions

  1. Reproduce with curl -IL <url> and read the status line
  2. Fix the URL/version in the download request for 404/410
  3. Check DNS/proxy if curl fails the same way
  4. Retry later only for 429 and 5xx; never for 404/403

Example fix

// before
finalURL, err := client.GetFinalURL(ctx, r.URL)
if err != nil {
    return err
}
// after: classify before deciding to retry
finalURL, err := client.GetFinalURL(ctx, r.URL)
if err != nil {
    var se *downloader.HTTPStatusError
    if errors.As(err, &se) && (se.StatusCode >= 500 || se.StatusCode == 429) {
        // transient: safe to retry with backoff
    }
}
Defensive patterns

Strategy: retry

Type guard

func classifyResolve(err error) (retryable bool, reason string) {
    var ne *downloader.NetworkError
    if errors.As(err, &ne) {
        return true, "network: " + ne.Error()
    }
    var he *downloader.HTTPStatusError
    if errors.As(err, &he) {
        if he.StatusCode >= 500 || he.StatusCode == 429 {
            return true, "server busy"
        }
        return false, he.Error() // 404/403: fix the URL, do not retry
    }
    return false, "unknown"
}

Try / catch

var lastErr error
for attempt := 0; attempt < 3; attempt++ {
    finalURL, lastErr = client.GetFinalURL(ctx, u)
    if lastErr == nil {
        break
    }
    if retryable, _ := classifyResolve(lastErr); !retryable {
        return lastErr
    }
    time.Sleep(time.Duration(1<<attempt) * time.Second)
}
if lastErr != nil {
    return lastErr
}

Prevention

When it happens

Trigger: DNS cannot resolve the host; proxy/firewall blocks the HEAD request; artifact URL pins a version that no longer exists (404); GitHub rate limits releases (403/429); server answers HEAD with 405.

Common situations: Pinned version no longer published upstream; corporate proxies; mirrors that dropped files; typos in release URLs.

Related errors


AI-assisted analysis of abiosoft/colima@c3a5f9184d (2026-08-15). Data as JSON: /api/errors/cf8175cf8916d143. Report an issue: GitHub.