vxcontrol/pentagi · error
failed to create http client: %w
Error message
failed to create http client: %w
What it means
newSearchService returns 'failed to create http client: %w' when system.GetHTTPClient(g.cfg) cannot construct the shared proxy/TLS-aware HTTP client. It is wrapped by Handle into a Fatal error, so Google is skipped for the query. This is a local client-construction failure — no Google request was made.
Source
Thrown at backend/pkg/tools/searchers/google.go:116
return g.formatResults(resp), nil
}
func (g *google) formatResults(res *customsearch.Search) string {
var writer strings.Builder
for i, item := range res.Items {
writer.WriteString(fmt.Sprintf("# %d. %s\n\n", i+1, item.Title))
writer.WriteString(fmt.Sprintf("## URL\n%s\n\n", item.Link))
writer.WriteString(fmt.Sprintf("## Snippet\n\n%s\n\n", item.Snippet))
}
return writer.String()
}
func (g *google) newSearchService(ctx context.Context) (*customsearch.Service, error) {
client, err := system.GetHTTPClient(g.cfg)
if err != nil {
return nil, fmt.Errorf("failed to create http client: %w", err)
}
// google.golang.org/api normally injects the API key through the HTTP transport it
// builds itself. But we MUST supply our own proxy/TLS client via WithHTTPClient, and
// WithHTTPClient takes precedence — it replaces that transport, so option.WithAPIKey
// is silently dropped and requests go out unauthenticated (HTTP 403 "unregistered
// caller"). Attach the key ourselves as the `key` query parameter (the documented
// Custom Search auth) by wrapping the proxy client's transport.
client.Transport = &googleAPIKeyTransport{
key: g.apiKey(),
base: client.Transport,
}
svc, err := customsearch.NewService(ctx, option.WithHTTPClient(client))
if err != nil {
return nil, fmt.Errorf("failed to create google search service: %v", err)
}
View on GitHub (pinned to ea665308ba)
Solutions
- Inspect the wrapped cause and fix the offending config value (proxy URL, CA cert path)
- Validate HTTPS_PROXY/HTTP_PROXY/NO_PROXY and CA bundle env vars in .env and docker-compose.yml
- Mount the CA certificate file into the container if a custom CA is required
- Test locally: the same GetHTTPClient is used by other engines, so if all engines fail, the problem is shared client config, not Google
Example fix
// before HTTPS_PROXY=proxy.internal:3128 // after (valid URL with scheme) HTTPS_PROXY=http://proxy.internal:3128
Defensive patterns
Strategy: validation
Validate before calling
// validate client construction at startup, before any search
if _, err := system.GetHTTPClient(cfg); err != nil {
log.Fatalf("invalid proxy/TLS config: %v", err)
} Prevention
- Parse HTTPS_PROXY/HTTP_PROXY with url.Parse and check scheme at startup
- Verify CA bundle paths are mounted and readable inside the container
- Since all engines share GetHTTPClient, add it to an init smoke test
When it happens
Trigger: system.GetHTTPClient fails loading proxy configuration or TLS material: malformed HTTPS_PROXY URL, missing/unreadable CA certificate file, or invalid TLS config derived from cfg.
Common situations: HTTPS_PROXY set to an invalid URL in .env/docker-compose; custom CA bundle path wrong or file not mounted into the container; TLS config env vars misformatted after a config refactor.
Related errors
- failed to create http client: %w
- failed to create http client: %w
- failed to create http client: %w
- failed to create http client: %w
- failed to create http client: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/6add2253a958fb4d.
Report an issue: GitHub.