googleapis/mcp-toolbox · error
operation finished with error: %s
Error message
operation finished with error: %s
What it means
The tracked Cloud SQL operation completed (Status == "DONE") but reported an error in its op.Error field. The library marshals the OperationError details into JSON and returns them as this error so the user sees why the create/update/delete failed. This is a pass-through of Google's server-side operation failure, not a client bug.
Source
Thrown at internal/sources/cloudsqladmin/cloud_sql_admin.go:359
}
func (s *Source) GetWaitForOperations(ctx context.Context, service *sqladmin.Service, project, operation, connectionMessageTemplate string, delay time.Duration) (any, error) {
logger, err := util.LoggerFromContext(ctx)
if err != nil {
return nil, err
}
op, err := service.Operations.Get(project, operation).Do()
if err != nil {
logger.DebugContext(ctx, fmt.Sprintf("error getting operation: %s, retrying in %v", err, delay))
} else {
if op.Status == "DONE" {
if op.Error != nil {
var errorBytes []byte
errorBytes, err = json.Marshal(op.Error)
if err != nil {
return nil, fmt.Errorf("operation finished with error but could not marshal error object: %w", err)
}
return nil, fmt.Errorf("operation finished with error: %s", string(errorBytes))
}
var opBytes []byte
opBytes, err = op.MarshalJSON()
if err != nil {
return nil, fmt.Errorf("could not marshal operation: %w", err)
}
var data map[string]any
if err := json.Unmarshal(opBytes, &data); err != nil {
return nil, fmt.Errorf("could not unmarshal operation: %w", err)
}
if msg, ok := generateCloudSQLConnectionMessage(ctx, s, logger, data, connectionMessageTemplate); ok {
return msg, nil
}
return string(opBytes), nil
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Parse the JSON error payload (contains errors[].code, message) to see the exact provisioning failure
- Fix the reported resource constraint (region, tier, disk size, IP range, quota) and retry the operation
- Verify the target project has Cloud SQL Admin API enabled and required service accounts are healthy
- Use gcloud sql operations describe <operation> for the same operation to cross-check details
Example fix
// before (caller treating generic failure)
result, err := src.GetWaitForOperations(ctx, service, project, opName, tpl, delay)
if err != nil {
log.Fatalf("failed: %v", err)
}
// after
result, err := src.GetWaitForOperations(ctx, service, project, opName, tpl, delay)
if err != nil {
var opErrs struct {
Errors []struct{ Code, Message string } `json:"errors"`
}
if inner := err.Error(); strings.HasPrefix(inner, "operation finished with error: ") {
_ = json.Unmarshal([]byte(strings.TrimPrefix(inner, "operation finished with error: ")), &opErrs)
}
log.Fatalf("cloudsql operation failed: %+v", opErrs.Errors)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Poll operation status and fail fast is not possible pre-call, but validate provisioning constraints first
func validateProvisioning(tier, region, dbVersion, diskGB int64_name string) error {
minDisk := map[string]int64{"MYSQL_8_0": 10, "POSTGRES_15": 10, "SQLSERVER_2022_STANDARD": 20}
if min, ok := minDisk[dbVersion]; ok && diskGB < min {
return fmt.Errorf("disk %dGB below minimum %dGB for %s", diskGB, min, dbVersion)
}
return nil
} Type guard
// Extract structured failure details from the error string the library returns
type cloudSQLOpError struct {
Errors []struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"errors"`
}
func parseCloudSQLOperationError(err error) (*cloudSQLOpError, bool) {
const prefix = "operation finished with error: "
s := err.Error()
if !strings.HasPrefix(s, prefix) {
return nil, false
}
var ce cloudSQLOpError
if json.Unmarshal([]byte(strings.TrimPrefix(s, prefix)), &ce) != nil {
return nil, false
}
return &ce, true
} Try / catch
for {
result, err := src.GetWaitForOperations(ctx, service, project, opName, tpl, delay)
if err != nil {
if ce, ok := parseCloudSQLOperationError(err); ok {
for _, e := range ce.Errors {
log.Printf("provisioning failed [%s]: %s", e.Code, e.Message)
}
}
return err
}
if result != nil { // DONE
return handleResult(result)
}
time.Sleep(delay)
} Prevention
- Check that the chosen VPC IP range has enough free addresses before creating instances
- Verify tier/region/dbVersion compatibility (some tiers are unavailable in some regions/versions)
- Confirm Cloud SQL Admin API is enabled and project quota is sufficient before long create flows
- Always poll to DONE and parse op.Error rather than assuming Insert success means provisioning success
When it happens
Trigger: Polling via GetWaitForOperations where service.Operations.Get returns an operation with Status "DONE" and op.Error != nil — e.g. instance creation failed server-side after the Insert call was accepted.
Common situations: Create-instance requests that passed validation but failed during provisioning: invalid tier/region combination, disk size below engine minimum, maintenance/maintenance-window conflicts, exceeded IP range in the VPC, or project quota issues discovered at provisioning time.
Related errors
- error creating instance: %w
- operation finished with error but could not marshal error ob
- could not marshal operation: %w
- could not unmarshal operation: %w
- failed to create instance: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/543bed200081c71e.
Report an issue: GitHub.