hasura/graphql-engine · error
failed to obtain plugin archive: %w
Error message
failed to obtain plugin archive: %w
What it means
The plugin downloader's fetch stage failed: the injected Fetcher's Get(url) returned an error before any bytes were read. This surfaces network/DNS/TLS/HTTP problems from obtaining the plugin archive and is wrapped under op 'download.download'.
Source
Thrown at cli/plugins/download/downloader.go:40
stderrors "errors"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
)
// download gets a file from the internet in memory and writes it content
// to a Verifier.
func download(url string, verifier Verifier, fetcher Fetcher) (io.ReaderAt, int64, error) {
var op errors.Op = "download.download"
body, err := fetcher.Get(url)
if err != nil {
return nil, 0, errors.E(op, fmt.Errorf("failed to obtain plugin archive: %w", err))
}
defer body.Close()
data, err := io.ReadAll(io.TeeReader(body, verifier))
if err != nil {
return nil, 0, errors.E(op, fmt.Errorf("could not read archive: %w", err))
}
err = verifier.Verify()
if err != nil {
return bytes.NewReader(data), int64(len(data)), errors.E(op, err)
}
return bytes.NewReader(data), int64(len(data)), nil
}
// extractZIP extracts a zip file into the target directory.
func extractZIP(targetDir, fileName string, read io.ReaderAt, size int64) error {View on GitHub (pinned to 724551b9ae)
Solutions
- Verify the plugin download URL is correct and reachable (curl -fL <url>).
- Check network egress: DNS, proxy env vars (HTTP_PROXY/HTTPS_PROXY), and firewall rules from the machine/CI runner.
- If behind a TLS-intercepting proxy, install the required CA cert or configure the Fetcher's HTTP client with the corporate root CA.
- Retry — transient network failures are a common cause; implement retry with backoff in the Fetcher.
Example fix
// before
body, err := http.Get(pluginURL) // fails with TLS/proxy errors
// after
client := &http.Client{Timeout: 30 * time.Second}
body, err := client.Get(pluginURL) Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight reachability check before calling Get
if resp, err := http.Head(pluginURL); err != nil || resp.StatusCode >= 400 {
return fmt.Errorf("plugin host unreachable: %v", err)
} Try / catch
var derr error
for i := 0; i < 3; i++ {
if _, err := downloader.Get(...); err == nil { break }
derr = err
time.Sleep(time.Duration(i+1) * time.Second)
} Prevention
- Configure HTTP_PROXY/HTTPS_PROXY in corporate networks
- Set sane timeouts on the Fetcher's http.Client
- Validate plugin URLs against a trusted registry/list before download
When it happens
Trigger: Calling Get (which calls download) with a plugin URL that is unreachable: DNS resolution failure, connection refused, TLS verification error, 4xx/5xx status handled by the Fetcher, a proxy blocking the request, or an air-gapped environment.
Common situations: Corporate proxy or firewall blocking the plugin host; mistyped or stale plugin URL; the plugin host is temporarily down; custom CA certificates missing so TLS fails; offline/CI environments without network egress.
Related errors
- could not read archive: %w
- Error while making the HTTP request to the pre-response plug
- Reqwest error: {0}
- Error while making the HTTP request to the pre-parse plugin
- Reqwest error: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/1215f515e32aa1ab.
Report an issue: GitHub.