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
- Verify credentials exist and are valid: gcloud auth application-default login or check GOOGLE_APPLICATION_CREDENTIALS
- Ensure the instance/pod has compute.readonly (or compute) scope or workload identity with compute.viewer
- Confirm the metadata server is reachable (curl -H 'Metadata-Flavor: Google' http://metadata.google.internal)
- Check network/proxy settings that could block the compute API endpoint
- 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
- Attach compute.readonly scope or workload identity to the verifier's instance/pod
- Keep GOOGLE_APPLICATION_CREDENTIALS valid and rotate keys
- Confirm metadata server reachability at startup
- Enable the Compute Engine API in the project
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
- error building compute API client: %v
- creating gce IPAM controller: %w
- error listing zones: %v
- unable to determine zones in region %q
- error getting ForwardingRule %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/14e78dbd47e50b96.
Report an issue: GitHub.