grpc/grpc-go · error
ALTS: untrusted platform. ALTS is only supported on GCP
Error message
ALTS: untrusted platform. ALTS is only supported on GCP
What it means
ErrUntrustedPlatform (credentials/alts/alts.go:68-71) is returned from both altsTC.ClientHandshake and ServerHandshake when vmOnGCP is false. vmOnGCP is set once via googlecloud.OnGCE() (alts.go:155) — ALTS relies on a hypervisor-provided handshaker service whose trustworthiness is only guaranteed on GCE/GKE/Cloud Run.
Source
Thrown at credentials/alts/alts.go:71
protocolVersionMinMajor = 2
protocolVersionMinMinor = 1
)
var (
vmOnGCP bool
once sync.Once
maxRPCVersion = &altspb.RpcProtocolVersions_Version{
Major: protocolVersionMaxMajor,
Minor: protocolVersionMaxMinor,
}
minRPCVersion = &altspb.RpcProtocolVersions_Version{
Major: protocolVersionMinMajor,
Minor: protocolVersionMinMinor,
}
// ErrUntrustedPlatform is returned from ClientHandshake and
// ServerHandshake is running on a platform where the trustworthiness of
// the handshaker service is not guaranteed.
ErrUntrustedPlatform = errors.New("ALTS: untrusted platform. ALTS is only supported on GCP")
logger = grpclog.Component("alts")
)
// AuthInfo exposes security information from the ALTS handshake to the
// application. This interface is to be implemented by ALTS. Users should not
// need a brand new implementation of this interface. For situations like
// testing, any new implementation should embed this interface. This allows
// ALTS to add new methods to this interface.
type AuthInfo interface {
// ApplicationProtocol returns application protocol negotiated for the
// ALTS connection.
ApplicationProtocol() string
// RecordProtocol returns the record protocol negotiated for the ALTS
// connection.
RecordProtocol() string
// SecurityLevel returns the security level of the created ALTS secure
// channel.
SecurityLevel() altspb.SecurityLevelView on GitHub (pinned to 03255a9237)
Solutions
- Deploy the workload to GCP (GCE/GKE/Cloud Run/Cloud Functions) where the ALTS handshaker is available.
- Off-GCP, switch to TLS: grpc.WithTransportCredentials(credentials.NewTLS(tlsConf)) instead of ALTS.
- For local dev use insecure.NewCredentials() explicitly (never in production).
- In ALTS unit tests, set the unexported vmOnGCP via an internal test build or run the test on GCP.
Example fix
// before — ALTS off GCP
cc, _ := grpc.NewClient(target,
grpc.WithTransportCredentials(alts.NewClientCreds(opts)))
// handshake error: ALTS: untrusted platform. ALTS is only supported on GCP
// after — TLS off GCP, ALTS only on GCP
var creds credentials.TransportCredentials
if onGCP {
creds = alts.NewClientCreds(opts)
} else {
creds = credentials.NewTLS(tlsConf)
}
cc, _ := grpc.NewClient(target, grpc.WithTransportCredentials(creds)) Defensive patterns
Strategy: fallback
Validate before calling
// Choose creds by environment so ALTS is only used on GCP
func pickCreds(onGCP bool) credentials.TransportCredentials {
if onGCP {
return alts.NewClientCreds(alts.DefaultClientOptions())
}
return credentials.NewTLS(&tls.Config{ServerName: server})
} Try / catch
if errors.Is(err, alts.ErrUntrustedPlatform) {
// not on GCP; fall back to TLS or fail explicitly
creds = credentials.NewTLS(tlsConf)
} Prevention
- Gate ALTS behind a GCP environment check; prefer TLS off-GCP.
- In ALTS tests, force vmOnGCP=true via the internal test package.
- Document per-environment credential selection in service config.
When it happens
Trigger: Code using alts.NewClientCreds()/alts.NewServerCreds() runs the handshake (clientconn.go dial → transport → ClientHandshake at alts.go:172-175, or server side at alts.go:218-221) on a host where googlecloud.OnGCE() returned false (not a GCE metadata server).
Common situations: Running ALTS locally or on AWS/on-prem; CI that is not on GCP; tests that forgot to force vmOnGCP=true (see alts_test.go:58-62); a container without metadata-server access.
Related errors
- client-side auth info is not of type alts.AuthInfo
- server-side auth info is not of type alts.AuthInfo
- grpc: no transport security set (use grpc.WithTransportCrede
- grpc: credentials.Bundle may not be used with individual Tra
- grpc: credentials.Bundle must return non-nil transport crede
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/aa034b380980cf24.
Report an issue: GitHub.