googleapis/mcp-toolbox · error

error listing AlloyDB users

Error message

error listing AlloyDB users: %w

What it means

This error wraps a failure from the AlloyDB Admin API Users.List call, which enumerates users under a cluster. It indicates the REST list request returned an HTTP error or failed in transport. The original Google API error remains accessible through the wrapped chain.

Solutions

  1. Verify the cluster exists and the path project/location/cluster is correct
  2. Refresh the access token and confirm it has cloud-platform or alloydb.admin scope
  3. Check the AlloyDB Admin API is enabled in the project
  4. Retry transient 5xx/429 errors with backoff
  5. Inspect the wrapped *googleapi.Error to distinguish 404 from 403

Example fix

// before
resp, err := service.Projects.Locations.Clusters.Users.List(urlString).Do()
if err != nil { return nil, fmt.Errorf("error listing AlloyDB users: %w", err) }
// after
resp, err := service.Projects.Locations.Clusters.Users.List(urlString).Do()
if err != nil {
    var gerr *googleapi.Error
    if errors.As(err, &gerr) && gerr.Code == 404 {
        return nil, fmt.Errorf("cluster %s not found, cannot list users: %w", cluster, err)
    }
    return nil, fmt.Errorf("error listing AlloyDB users: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: validate inputs and cluster existence before ListUsers
if cluster == "" {
    return fmt.Errorf("cluster is required")
}
if _, err := s.GetCluster(ctx, project, location, cluster, accessToken); err != nil {
    return fmt.Errorf("cluster %s not found: %w", cluster, err)
}

Type guard

func IsPermissionDenied(err error) bool {
    var gerr *googleapi.Error
    return errors.As(err, &gerr) && gerr.Code == 403
}

Try / catch

users, err := s.ListUsers(ctx, project, location, cluster, accessToken)
if err != nil {
    var gerr *googleapi.Error
    if errors.As(err, &gerr) {
        if gerr.Code == 403 {
            return nil, fmt.Errorf("missing alloydb.admin permission: %v", gerr)
        }
        if gerr.Code == 429 || gerr.Code >= 500 {
            return retryWithBackoff(...)
        }
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling Source.ListUsers with a bad cluster resource path, a nonexistent cluster, insufficient token permissions, or a network error during Users.List(urlString).Do().

Common situations: Polling users against a deleted cluster, tokens from a different project than the cluster, disabled AlloyDB API, and intermittent network failures.

Related errors


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

Appendix: source

Thrown at internal/sources/alloydbadmin/alloydbadmin.go:322

	resp, err := service.Projects.Locations.Clusters.Instances.List(urlString).Do()
	if err != nil {
		return nil, fmt.Errorf("error listing AlloyDB instances: %w", err)
	}
	return resp, nil
}

func (s *Source) ListUsers(ctx context.Context, project, location, cluster, accessToken string) (any, error) {
	service, err := s.getService(ctx, accessToken)
	if err != nil {
		return nil, err
	}

	urlString := fmt.Sprintf("projects/%s/locations/%s/clusters/%s", project, location, cluster)

	resp, err := service.Projects.Locations.Clusters.Users.List(urlString).Do()
	if err != nil {
		return nil, fmt.Errorf("error listing AlloyDB users: %w", err)
	}
	return resp, nil
}

func (s *Source) GetOperations(ctx context.Context, project, location, operation, connectionMessageTemplate string, delay time.Duration, accessToken string) (any, error) {
	logger, err := util.LoggerFromContext(ctx)
	if err != nil {
		return nil, err
	}

	service, err := s.getService(ctx, accessToken)
	if err != nil {
		return nil, err
	}

	name := fmt.Sprintf("projects/%s/locations/%s/operations/%s", project, location, operation)

	op, err := service.Projects.Locations.Operations.Get(name).Do()

View on GitHub (pinned to 8cc6e09de2)