kubernetes/kops · critical

error building compute API client: %w

Error message

error building compute API client: %w

What it means

NewTPMVerifier builds a Google Compute Engine API client (compute.NewService) that it later uses to fetch VM state for verification. If constructing the compute service fails (credentials missing/invalid, transport error), the verifier cannot be constructed and this error is returned to main.

Source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:62

	"k8s.io/kops/upup/pkg/fi/cloudup/gce/gcemetadata"
	gcetpm "k8s.io/kops/upup/pkg/fi/cloudup/gce/tpm"
)

type tpmVerifier struct {
	opt gcetpm.TPMVerifierOptions

	computeClient *compute.Service

	capiManager *capimanager.Manager
}

// NewTPMVerifier constructs a new TPM verifier for GCE.
func NewTPMVerifier(opt *gcetpm.TPMVerifierOptions, capiManager *capimanager.Manager) (bootstrap.Verifier, error) {
	ctx := context.Background()

	computeClient, err := compute.NewService(ctx)
	if err != nil {
		return nil, fmt.Errorf("error building compute API client: %w", err)
	}

	return &tpmVerifier{
		opt:           *opt,
		computeClient: computeClient,
		capiManager:   capiManager,
	}, nil
}

var _ bootstrap.Verifier = (*tpmVerifier)(nil)

func (v *tpmVerifier) VerifyToken(ctx context.Context, rawRequest *http.Request, authToken string, body []byte) (*bootstrap.VerifyResult, error) {
	// Reminder: we shouldn't trust any data we get from the client until we've checked the signature (and even then...)
	// Thankfully the GCE SDK does seem to escape the parameters correctly, for example.

	if !strings.HasPrefix(authToken, gcetpm.GCETPMAuthenticationTokenPrefix) {
		return nil, bootstrap.ErrNotThisVerifier
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify credentials exist and are valid: gcloud auth application-default login or check GOOGLE_APPLICATION_CREDENTIALS
  2. Ensure the instance/pod has compute.readonly (or compute) scope or workload identity with compute.viewer
  3. Confirm the metadata server is reachable (curl -H 'Metadata-Flavor: Google' http://metadata.google.internal)
  4. Check network/proxy settings that could block the compute API endpoint
  5. Grant the service account the required compute API permissions and enable the Compute Engine API on the project

Example fix

// before
computeClient, err := compute.NewService(ctx)
// after
import "google.golang.org/api/option"
computeClient, err := compute.NewService(ctx, option.WithCredentialsFile("/etc/gcp/sa.json"))
Defensive patterns

Strategy: try-catch

Validate before calling

// before constructing the verifier
creds, err := google.FindDefaultCredentials(ctx, compute.ComputeReadonlyScope)
if err != nil {
    return fmt.Errorf("no GCP credentials: %w", err)
}

Try / catch

verifier, err := gcetpmverifier.NewTPMVerifier(opt, capiManager)
if err != nil {
    if strings.Contains(err.Error(), "compute API client") {
        return fmt.Errorf("check GCP credentials/scopes for the verifier: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: compute.NewService(ctx) fails at verifier startup: no Application Default Credentials, unreadable GOOGLE_APPLICATION_CREDENTIALS, missing required scopes, or failure building the http client (network/proxy errors).

Common situations: Node/server pod missing GCP service account or workload identity binding; metadata server unreachable (not running on GCE); GOOGLE_APPLICATION_CREDENTIALS pointing to a deleted/invalid key file; missing compute scopes on the instance.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/14e78dbd47e50b96. Report an issue: GitHub.