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

  1. Parse the JSON error payload (contains errors[].code, message) to see the exact provisioning failure
  2. Fix the reported resource constraint (region, tier, disk size, IP range, quota) and retry the operation
  3. Verify the target project has Cloud SQL Admin API enabled and required service accounts are healthy
  4. 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

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


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