grpc/grpc-go · error
credentials: failed to append certificates
Error message
credentials: failed to append certificates
What it means
NewClientTLSFromFileWithALPNDisabled read the cert file successfully but x509.CertPool.AppendCertsFromPEM returned false, meaning the bytes contained no PEM-encoded certificate blocks that Go's parser could add. This is the experimental ALPN-disabled variant of the standard credentials helper; it surfaces a malformed or empty CA bundle.
Source
Thrown at experimental/credentials/tls.go:205
return NewTLSWithALPNDisabled(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
}
// NewClientTLSFromFileWithALPNDisabled constructs TLS credentials from the
// provided root certificate authority certificate file(s) to validate server
// connections. If certificates to establish the identity of the client need to
// be included in the credentials (eg: for mTLS), use NewTLS instead, where a
// complete tls.Config can be specified.
// serverNameOverride is for testing only. If set to a non empty string,
// it will override the virtual host name of authority (e.g. :authority header
// field) in requests. ALPN verification is disabled.
func NewClientTLSFromFileWithALPNDisabled(certFile, serverNameOverride string) (credentials.TransportCredentials, error) {
b, err := os.ReadFile(certFile)
if err != nil {
return nil, err
}
cp := x509.NewCertPool()
if !cp.AppendCertsFromPEM(b) {
return nil, fmt.Errorf("credentials: failed to append certificates")
}
return NewTLSWithALPNDisabled(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
}
// NewServerTLSFromCertWithALPNDisabled constructs TLS credentials from the
// input certificate for server. ALPN verification is disabled.
func NewServerTLSFromCertWithALPNDisabled(cert *tls.Certificate) credentials.TransportCredentials {
return NewTLSWithALPNDisabled(&tls.Config{Certificates: []tls.Certificate{*cert}})
}
// NewServerTLSFromFileWithALPNDisabled constructs TLS credentials from the
// input certificate file and key file for server. ALPN verification is disabled.
func NewServerTLSFromFileWithALPNDisabled(certFile, keyFile string) (credentials.TransportCredentials, error) {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
return NewTLSWithALPNDisabled(&tls.Config{Certificates: []tls.Certificate{cert}}), nilView on GitHub (pinned to 03255a9237)
Solutions
- Confirm the file is PEM-encoded and contains at least one 'BEGIN CERTIFICATE' block: `openssl x509 -in <file> -noout -text`.
- If the cert is DER, convert with `openssl x509 -inform DER -in cert.der -out cert.pem`.
- Check the file is non-empty and is the CA/root bundle, not the private key or leaf-only chain (this helper expects root CAs).
Example fix
// before
creds, err := expcreds.NewClientTLSFromFileWithALPNDisabled("/tls/server.key", "example.com")
// after
creds, err := expcreds.NewClientTLSFromFileWithALPNDisabled("/tls/ca.crt", "example.com") Defensive patterns
Strategy: validation
Validate before calling
import (
"crypto/x509"
"encoding/pem"
"os"
)
func validPEMCABundle(path string) error {
b, err := os.ReadFile(path)
if err != nil { return err }
pool := x509.NewCertPool()
if !pool.AppendCertsFromPEM(b) {
return errors.New("file has no PEM CERTIFICATE blocks")
}
if pem.Decode(b) == nil { return errors.New("not PEM-encoded") }
return nil
} Try / catch
creds, err := expcreds.NewClientTLSFromFileWithALPNDisabled(path, sni)
if err != nil { return fmt.Errorf("load CA bundle %s: %w", path, err) } Prevention
- Use `openssl x509 -in <path> -noout -text` to confirm the file is a valid PEM cert.
- Mount the CA bundle (not the key) as the file argument.
- Convert DER to PEM before loading.
When it happens
Trigger: Passing a path to a DER-encoded cert, a private key file, an HTML error page, or an empty file to NewClientTLSFromFileWithALPNDisabled. Also triggered when the PEM has only a key block (BEGIN PRIVATE KEY) and no CERTIFICATE blocks.
Common situations: Mounting the wrong secret in Kubernetes (key instead of cert); pointing at a symlink that resolves to nothing; downloading a CA bundle over HTTP and getting a 404 HTML body; using a cert in DER format instead of PEM.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- 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
- no DN found in certificate issuer
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/3c0a3bf022490e77.
Report an issue: GitHub.