pulumi/pulumi · error

failed to download %s: %w

Error message

failed to download %s: %w

What it means

Thrown when the automation API downloads the pulumi install script over HTTP and the request fails after retries. It wraps the network error with the failing URL. Indicates connectivity, DNS, TLS, or HTTP status issues reaching the download host.

Source

Thrown at sdk/go/auto/cmd.go:176

		if err := installWindows(ctx, opts.Version, opts.Root); err != nil {
			return pulumiCommand{}, err
		}
	} else {
		if err := installPosix(ctx, opts.Version, opts.Root); err != nil {
			return pulumiCommand{}, err
		}
	}
	return NewPulumiCommand(opts)
}

func downloadToTmpFile(ctx context.Context, url, filePattern string) (_ string, err error) {
	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return "", err
	}
	resp, err := httputil.DoWithRetry(req, http.DefaultClient)
	if err != nil {
		return "", fmt.Errorf("failed to download %s: %w", url, err)
	}
	defer resp.Body.Close()
	scriptData, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("failed to read response from %s: %w", url, err)
	}
	tmp, err := os.CreateTemp("", filePattern)
	if err != nil {
		return "", err
	}
	scriptPath := tmp.Name()
	defer func() {
		if err != nil {
			os.Remove(scriptPath)
		}
	}()
	// The permissions here are ignored because the tmp file already exists.
	// We need to explicitly call chmod below to set the desired permissions.

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Verify network connectivity to the URL (curl -I https://get.pulumi.com/install.sh)
  2. Configure HTTP(S)_PROXY environment variables if behind a corporate proxy
  3. Pre-install the Pulumi CLI manually so the download path is not taken
  4. Retry later if the wrapped error indicates a 5xx/transient failure (the call already retries)

Example fix

// before
err := installPosix(ctx, v, root) // fails offline
// after
export HTTPS_PROXY=http://proxy.corp:8080
// or pre-install:
curl -fsSL https://get.pulumi.com/install.sh | sh
Defensive patterns

Strategy: retry

Validate before calling

req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://get.pulumi.com/install.sh", nil)
if _, err := http.DefaultClient.Do(req); err != nil {
    return fmt.Errorf("precheck: cannot reach get.pulumi.com: %w", err)
}

Type guard

func isNetworkErr(err error) bool {
    var ne net.Error
    return errors.As(err, &ne) || errors.Is(err, context.DeadlineExceeded)
}

Try / catch

err := install(ctx, version, root)
if err != nil {
    if strings.Contains(err.Error(), "failed to download") {
        return retryWithBackoff(ctx, 3, func() error { return install(ctx, version, root) })
    }
    return err
}

Prevention

When it happens

Trigger: Calling install (e.g. installPosix via pulumi install path in sdk/go/auto/cmd.go) when httputil.DoWithRetry on http.NewRequestWithContext GET to https://get.pulumi.com/install.sh fails — no network, DNS failure, proxy misconfig, or repeated 5xx.

Common situations: Running in an air-gapped/CI environment without internet; corporate proxy blocking get.pulumi.com; TLS interception certificates not trusted; transient provider outage.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/c12ecbd075ad140f. Report an issue: GitHub.