googleapis/mcp-toolbox · error

failed to search for VM

Error message

failed to search for VM: %w

What it means

FindVM pages through Compute Engine's AggregatedList of instances to locate a VM by name in a project. Any API error encountered during paging (other than the internal stopPaging sentinel) is wrapped in this error, distinct from the separate 'VM not found' case.

Solutions

  1. Grant the caller service account compute.instances.list permission (roles/compute.viewer) on the target project
  2. Verify the project ID is correct and the Compute Engine API is enabled
  3. Inspect the wrapped %w error for the underlying Google API status and retry on transient 5xx
  4. Check quotas and network connectivity/proxy settings to compute.googleapis.com

Example fix

// before
svc, err := cloudsqlconnect.GetComputeService(ctx, token) // token lacks compute scopes
vm, zone, err := cloudsqlconnect.FindVM(ctx, svc, project, vmName)
// after
// ensure token includes compute.readonly scope, then retry on transient errors
var vm *compute.Instance
var zone string
for attempt := 0; attempt < 3; attempt++ {
    vm, zone, err = cloudsqlconnect.FindVM(ctx, svc, project, vmName)
    if err == nil || !isTransient(err) { break }
    time.Sleep(time.Duration(attempt+1) * time.Second)
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight permission check
_, err := svc.Projects.Get(project).Do()
if err != nil {
    return fmt.Errorf("project %s not accessible or Compute API disabled: %w", project, err)
}

Try / catch

vm, zone, err := cloudsqlconnect.FindVM(ctx, svc, project, vmName)
if err != nil {
    var ge *googleapi.Error
    if errors.As(err, &ge) && ge.Code == 403 {
        return fmt.Errorf("grant compute.viewer on project %s", project)
    }
    if isTransient(err) { /* exponential backoff retry */ }
    return err
}

Prevention

When it happens

Trigger: The compute Service.AggregatedList call fails during iteration — quota exceeded, permission denied (missing compute.instances.list), invalid project ID, disabled Compute Engine API, or transient 5xx/network errors.

Common situations: Service account lacking compute.viewer on the project; wrong project ID in the connection name; Compute Engine API disabled; GKE/regional quota exhaustion; flaky network between the VM and googleapis.

Related errors


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

Appendix: source

Thrown at internal/util/cloudsqlconnect/gce.go:183

	// quotes for GCE's filter language regardless.
	req := service.Instances.AggregatedList(project).Filter(fmt.Sprintf("name eq %q", vmName))
	err := req.Pages(ctx, func(page *compute.InstanceAggregatedList) error {
		for zone, list := range page.Items {
			for _, instance := range list.Instances {
				if instance.Name != vmName {
					continue
				}
				foundInstances = append(foundInstances, instance)
				foundZones = append(foundZones, ExtractNetworkName(zone))
				if len(foundInstances) > 1 {
					return stopPaging
				}
			}
		}
		return nil
	})
	if err != nil && err != stopPaging {
		return nil, "", fmt.Errorf("failed to search for VM: %w", err)
	}

	switch len(foundInstances) {
	case 0:
		return nil, "", fmt.Errorf("VM %q not found in project %q", vmName, project)
	case 1:
		return foundInstances[0], foundZones[0], nil
	default:
		return nil, "", fmt.Errorf("multiple VMs named %q found in zones: %v - please specify vm_zone parameter", vmName, foundZones)
	}
}

// stringErr signals early termination from Pages without conflating with
// real API errors. Unexported: only FindVM's Pages callback uses it.
type stringErr string

func (e stringErr) Error() string { return string(e) }

View on GitHub (pinned to 8cc6e09de2)