grpc/grpc-go · error
credentials: cannot check peer: missing selected ALPN proper
Error message
credentials: cannot check peer: missing selected ALPN property. %s
What it means
Returned by tlsCreds.ClientHandshake in credentials/tls.go:151 when, after a successful TLS handshake, no ALPN protocol was negotiated (NegotiatedProtocol == "") and envconfig.EnforceALPNEnabled is true (the default). HTTP/2 over TLS requires ALPN, so grpc-go refuses connections to ALPN-less servers. The trailing %s points at issue #434 and the 1.67 enforcement change.
Source
Thrown at credentials/tls.go:151
return nil, nil, err
}
case <-ctx.Done():
conn.Close()
return nil, nil, ctx.Err()
}
// The negotiated protocol can be either of the following:
// 1. h2: When the server supports ALPN. Only HTTP/2 can be negotiated since
// it is the only protocol advertised by the client during the handshake.
// The tls library ensures that the server chooses a protocol advertised
// by the client.
// 2. "" (empty string): If the server doesn't support ALPN. ALPN is a requirement
// for using HTTP/2 over TLS. We can terminate the connection immediately.
np := conn.ConnectionState().NegotiatedProtocol
if np == "" {
if envconfig.EnforceALPNEnabled {
conn.Close()
return nil, nil, fmt.Errorf("credentials: cannot check peer: missing selected ALPN property. %s", alpnFailureHelpMessage)
}
logger.Warningf("Allowing TLS connection to server %q with ALPN disabled. TLS connections to servers with ALPN disabled will be disallowed in future grpc-go releases", cfg.ServerName)
}
tlsInfo := TLSInfo{
State: conn.ConnectionState(),
CommonAuthInfo: CommonAuthInfo{
SecurityLevel: PrivacyAndIntegrity,
},
}
id := credinternal.SPIFFEIDFromState(conn.ConnectionState())
if id != nil {
tlsInfo.SPIFFEID = id
}
return credinternal.WrapSyscallConn(rawConn, conn), tlsInfo, nil
}
func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
conn := tls.Server(rawConn, c.config)View on GitHub (pinned to 03255a9237)
Solutions
- Enable h2 ALPN on the server / TLS terminator (nginx: http2 + ssl_alpn, or grpc ALPN; Go server: rely on grpc's default NextProtos).
- As a temporary rollback, set GRPC_ENFORCE_ALPN_ENABLED=false in the client environment (will be removed in a future release).
- Bypass the ALPN-stripping proxy for the gRPC port.
Example fix
// before: client env (default) // GRPC_ENFORCE_ALPN_ENABLED unset -> enforcement on, connection fails // after (fix the server): nginx // listen 443 ssl http2; // ssl_alpn h2 http/1.1; // after (temporary client-side rollback) // export GRPC_ENFORCE_ALPN_ENABLED=false
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the server/terminator advertises h2 ALPN before enforcing.
// Client-side mitigation: do nothing if server is ALPN-capable.
// Temporary rollback only for migration:
// os.Setenv("GRPC_ENFORCE_ALPN_ENABLED", "false") // must be set before grpc imports init Try / catch
if strings.Contains(err.Error(), "missing selected ALPN property") {
// server lacks ALPN; enable h2 on the server/terminator or set
// GRPC_ENFORCE_ALPN_ENABLED=false as a temporary rollback
} Prevention
- Enable h2 ALPN on all TLS terminators in front of gRPC servers.
- Test the ALPN upgrade path in staging before enforcing in production.
- Treat GRPC_ENFORCE_ALPN_ENABLED=false as migration-only; track upstream removal.
When it happens
Trigger: Dialing a TLS server (or a proxy/terminator in front of it) that does not support ALPN, while GRPC_ENFORCE_ALPN_ENABLED is true (default). Common after upgrading grpc-go to >=1.67.
Common situations: Post-1.67 upgrade where TLS connections to an older server/proxy stopped working; an HAProxy/nginx/cloud LB that did not enable h2 ALPN; servers configured with TLS but no NextProtos.
Related errors
- cannot send secure credentials on an insecure connection: %v
- pemfile: certificate and key file must be in the same direct
- provider instance is closed
- xds: CertificateProvider to fetch trusted roots is missing,
- xds: CertificateProvider to fetch identity certificate is mi
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/285c741006b4f071.
Report an issue: GitHub.