GoogleContainerTools/skaffold · error

failed to get repository read access token for repo %v: %w

Error message

failed to get repository read access token for repo %v: %w

What it means

Fires in GetRepoInfo when acquiring a short-lived read-access token for a 2nd-gen Cloud Build (GCB) linked repository fails via the Repository Manager API. Wraps the token-fetch error, typically missing IAM permissions on the connection/repository or an invalid repository reference.

Source

Thrown at pkg/skaffold/gcbreposv2/repo_resolver.go:60

var RepositoryManagerClient = repositoryManagerClient

func GetRepoInfo(ctx context.Context, gcpProject, gcpRegion, gcpConnectionName, gcpRepoName string) (Repo, error) {
	cbRepoRef := fmt.Sprintf("projects/%v/locations/%v/connections/%v/repositories/%v", gcpProject, gcpRegion, gcpConnectionName, gcpRepoName)
	cbClient, err := RepositoryManagerClient(ctx)
	if err != nil {
		return Repo{}, fmt.Errorf("failed to create repository manager client: %w", err)
	}
	defer cbClient.Close()

	repoURI, err := getRepoURI(ctx, cbClient, cbRepoRef)
	if err != nil {
		return Repo{}, fmt.Errorf("failed to get remote URI for repository %v: %w", gcpRepoName, err)
	}

	readAccessToken, err := getRepoReadAccessToken(ctx, cbClient, cbRepoRef)
	if err != nil {
		return Repo{}, fmt.Errorf("failed to get repository read access token for repo %v: %w", gcpRepoName, err)
	}

	repoCloneURI, err := buildRepoURIWithToken(repoURI, readAccessToken)
	if err != nil {
		return Repo{}, fmt.Errorf("failed to clone repo %s: trouble building repo URI with token: %w", repoURI, err)
	}

	return Repo{
		URI:      repoURI,
		CloneURI: repoCloneURI,
	}, nil
}

func repositoryManagerClient(ctx context.Context) (cloudBuildRepoClient, error) {
	return cloudbuild.NewRepositoryManagerClient(ctx)
}

func getRepoURI(ctx context.Context, cbClient cloudBuildRepoClient, cbRepoRef string) (string, error) {

View on GitHub (pinned to a1189de023)

Solutions

  1. Ensure the identity has permission to fetch repository read access tokens (Cloud Build connection viewer/admin).
  2. Re-authenticate: `gcloud auth application-default login` or refresh the service-account key.
  3. Inspect the wrapped cause to distinguish PERMISSION_DENIED vs transport errors.
  4. Retry on transient 5xx / deadline errors.

Example fix

// before: generic Viewer role only
// after
gcloud projects add-iam-policy-binding PROJECT \
  --member=serviceAccount:SA \
  --role=roles/cloudbuild.connectionViewer
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm identity can call the token endpoint
_ = google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform")

Try / catch

repo, err := gcbreposv2.GetRepoInfo(ctx, proj, region, conn, name)
if err != nil && strings.Contains(err.Error(), "read access token") {
    return fmt.Errorf("identity lacks token permission; grant cloudbuild.connectionViewer: %w", err)
}

Prevention

When it happens

Trigger: Calling GetRepoInfo when the read-access-token RPC fails: credentials lacking the required scope, no permission to generate access tokens on the connection/repo, token API outage, or context cancellation.

Common situations: Service account with viewer but not the connection-specific token-generation permission; workload identity misconfiguration on GKE; expired/quota-limited credentials in long-running CI jobs.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/2d35dc69dc7304be. Report an issue: GitHub.