googleapis/mcp-toolbox · error

failed to send request: %w

Error message

failed to send request: %w

What it means

This error wraps a failure from client.Do(req) when sending the POST to the Conversational Analytics API. It covers transport-level failures: DNS resolution errors, connection refused/reset, TLS handshake failures, timeouts, or context cancellation.

Source

Thrown at internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go:285

}

func getStream(client *http.Client, url string, payload CAPayload, headers map[string]string, maxRows int) (string, error) {
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return "", fmt.Errorf("failed to marshal payload: %w", err)
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
	if err != nil {
		return "", fmt.Errorf("failed to create request: %w", err)
	}
	for k, v := range headers {
		req.Header.Set(k, v)
	}

	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return "", fmt.Errorf("API returned non-200 status: %d %s", resp.StatusCode, string(body))
	}

	var messages []map[string]any
	decoder := json.NewDecoder(resp.Body)
	dataMsgIdx := -1

	// The response is a JSON array, so we read the opening bracket.
	if _, err := decoder.Token(); err != nil {
		if err == io.EOF {
			return "", nil // Empty response is valid
		}
		return "", fmt.Errorf("error reading start of json array: %w", err)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Verify network egress to the Conversational Analytics endpoint (DNS + HTTPS) from the host running the toolbox (curl the endpoint).
  2. Check application default credentials: run `gcloud auth application-default login` or provide a valid service account via GOOGLE_APPLICATION_CREDENTIALS.
  3. If behind a proxy, set HTTPS_PROXY correctly; if in VPC-SC, add the required egress rule for the API.
  4. Check whether the request context was canceled upstream (client disconnect/timeout) and increase timeouts if needed.
  5. Retry with backoff for transient connection resets.

Example fix

// before: no egress
//   firewall blocks api.googleapis.com
// after: allow egress
//   gcloud services enable cloudaicompanion.googleapis.com
//   open HTTPS (443) to googleapis.com in firewall/proxy
Defensive patterns

Strategy: retry

Validate before calling

conn, err := net.DialTimeout("tcp", "api.googleapis.com:443", 5*time.Second)
if err != nil {
    return fmt.Errorf("no network egress to GDA endpoint: %w", err)
}
conn.Close()

Try / catch

var result any
err := retry.Do(3, time.Second, func() error {
    var e error
    result, e = tool.Invoke(ctx, params)
    return e
})
if err != nil {
    return fmt.Errorf("GDA unreachable after retries: %w", err)
}

Prevention

When it happens

Trigger: Invoke on the tool when the HTTP client (built from the source's token source) cannot reach the GDA endpoint: no network, blocked egress, DNS failure, TLS problems, or the request context is canceled before completion.

Common situations: Corporate firewall/proxy blocking api.googleapis.com; missing VPC Service Controls egress rules; running in an air-gapped environment; expired/unrefreshable credentials causing token-source failures surfaced as transport errors; long-running queries exceeding client timeouts.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/01a197e0dfe42565. Report an issue: GitHub.