googleapis/mcp-toolbox · error
failed to update cluster: %w
Error message
failed to update cluster: %w
What it means
This error wraps any failure returned by the Cloud Bigtable InstanceAdmin client's UpdateCluster call when the MCP tool invokes Source.UpdateCluster. The library wraps the underlying gRPC/API error with fmt.Errorf("failed to update cluster: %w", err), so the original cause (permissions, not found, quota, invalid nodes) is preserved via the %w chain. Inspect the wrapped error with errors.Unwrap or %v to see the real gRPC status.
Source
Thrown at internal/sources/bigtable/admin_wrappers.go:118
func (s *Source) CreateCluster(ctx context.Context, instanceId, clusterId, zone string, numNodes int32) (any, error) {
conf := &bigtable.ClusterConfig{
InstanceID: instanceId,
ClusterID: clusterId,
Zone: zone,
NumNodes: numNodes,
}
err := s.InstanceAdmin.CreateCluster(ctx, conf)
if err != nil {
return nil, fmt.Errorf("failed to create cluster: %w", err)
}
return map[string]string{"status": "cluster created successfully"}, nil
}
func (s *Source) UpdateCluster(ctx context.Context, instanceId, clusterId string, serveNodes int32) (any, error) {
err := s.InstanceAdmin.UpdateCluster(ctx, instanceId, clusterId, serveNodes)
if err != nil {
return nil, fmt.Errorf("failed to update cluster: %w", err)
}
return map[string]string{"status": "cluster updated successfully"}, nil
}
func (s *Source) DeleteCluster(ctx context.Context, instanceId, clusterId string) (any, error) {
err := s.InstanceAdmin.DeleteCluster(ctx, instanceId, clusterId)
if err != nil {
return nil, fmt.Errorf("failed to delete cluster: %w", err)
}
return map[string]string{"status": "cluster deleted successfully"}, nil
}
func (s *Source) GetTable(ctx context.Context, tableId string) (any, error) {
table, err := s.Admin.TableInfo(ctx, tableId)
if err != nil {
return nil, fmt.Errorf("failed to get table: %w", err)
}
return table, nilView on GitHub (pinned to 8cc6e09de2)
Solutions
- Verify instanceId and clusterId exist (list instances/clusters via admin console or bigtable list tools) and use the ID, not the display name.
- Check IAM: the caller's service account needs roles/bigtable.admin (or at least bigtable.clusters.update).
- Inspect the wrapped error (gRPC status code) to distinguish NotFound vs PermissionDenied vs ResourceExhausted; fix the corresponding cause.
- Retry transient failures (Unavailable/DeadlineExceeded) with backoff; check node quota if ResourceExhausted.
Example fix
// before: blindly wrapping without surfacing the gRPC status
return nil, fmt.Errorf("failed to update cluster: %w", err)
// after: caller-side discrimination of the wrapped error
var st *status.Status
if errors.As(err, &st) && st.Code() == codes.NotFound {
log.Printf("cluster %s not found in instance %s", clusterId, instanceId)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: verify inputs before calling UpdateCluster
if instanceId == "" || clusterId == "" {
return fmt.Errorf("instanceId and clusterId are required")
}
if serveNodes <= 0 {
return fmt.Errorf("serveNodes must be a positive integer")
} Type guard
func isNotFound(err error) bool {
return status.Code(err) == codes.NotFound
} Try / catch
if err := src.UpdateCluster(ctx, inst, cluster, nodes); err != nil {
switch status.Code(err) {
case codes.NotFound:
// handle missing cluster
case codes.PermissionDenied:
// surface IAM guidance
case codes.Unavailable, codes.DeadlineExceeded:
// retry with backoff
default:
log.Printf("update cluster failed: %v", err)
}
} Prevention
- Use the exact cluster/instance IDs (not display names) from list operations.
- Assign roles/bigtable.admin to the service account used by the tool.
- Pre-validate serveNodes against cluster min/max and autoscaling settings.
- Implement exponential-backoff retry for codes.Unavailable and DeadlineExceeded.
When it happens
Trigger: Calling the bigtable update_cluster tool (Source.UpdateCluster in internal/sources/bigtable/admin_wrappers.go:118) where s.InstanceAdmin.UpdateCluster(ctx, instanceId, clusterId, serveNodes) returns a non-nil error: instance or cluster ID does not exist, caller lacks bigtable.clusters.update IAM permission, serveNodes value is invalid, or the gRPC call fails (timeout, network, quota).
Common situations: Typo in instanceId/clusterId (IDs are distinct from display names); service account missing Bigtable Admin role; autoscaling-enabled clusters rejecting manual serveNodes changes; transient gRPC Unavailable during zone maintenance; exceeding node quota in a region.
Related errors
- failed to delete cluster: %w
- failed to get table: %w
- failed to create table: %w
- failed to delete table: %w
- failed to create column family: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/85756e478b314141.
Report an issue: GitHub.