{"record":{"id":"3c0a3bf022490e77","repo":"grpc/grpc-go","slug":"credentials-failed-to-append-certificates-3c0a3b","errorCode":null,"errorMessage":"credentials: failed to append certificates","messagePattern":"credentials: failed to append certificates","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"experimental/credentials/tls.go","lineNumber":205,"sourceCode":"\treturn NewTLSWithALPNDisabled(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})\n}\n\n// NewClientTLSFromFileWithALPNDisabled constructs TLS credentials from the\n// provided root certificate authority certificate file(s) to validate server\n// connections. If certificates to establish the identity of the client need to\n// be included in the credentials (eg: for mTLS), use NewTLS instead, where a\n// complete tls.Config can be specified.\n// serverNameOverride is for testing only. If set to a non empty string,\n// it will override the virtual host name of authority (e.g. :authority header\n// field) in requests. ALPN verification is disabled.\nfunc NewClientTLSFromFileWithALPNDisabled(certFile, serverNameOverride string) (credentials.TransportCredentials, error) {\n\tb, err := os.ReadFile(certFile)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcp := x509.NewCertPool()\n\tif !cp.AppendCertsFromPEM(b) {\n\t\treturn nil, fmt.Errorf(\"credentials: failed to append certificates\")\n\t}\n\treturn NewTLSWithALPNDisabled(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil\n}\n\n// NewServerTLSFromCertWithALPNDisabled constructs TLS credentials from the\n// input certificate for server. ALPN verification is disabled.\nfunc NewServerTLSFromCertWithALPNDisabled(cert *tls.Certificate) credentials.TransportCredentials {\n\treturn NewTLSWithALPNDisabled(&tls.Config{Certificates: []tls.Certificate{*cert}})\n}\n\n// NewServerTLSFromFileWithALPNDisabled constructs TLS credentials from the\n// input certificate file and key file for server. ALPN verification is disabled.\nfunc NewServerTLSFromFileWithALPNDisabled(certFile, keyFile string) (credentials.TransportCredentials, error) {\n\tcert, err := tls.LoadX509KeyPair(certFile, keyFile)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewTLSWithALPNDisabled(&tls.Config{Certificates: []tls.Certificate{cert}}), nil","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/experimental/credentials/tls.go#L187-L223","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\ncreds, err := expcreds.NewClientTLSFromFileWithALPNDisabled(\"/tls/server.key\", \"example.com\")\n\n// after\ncreds, err := expcreds.NewClientTLSFromFileWithALPNDisabled(\"/tls/ca.crt\", \"example.com\")","handlingStrategy":"validation","validationCode":"import (\n    \"crypto/x509\"\n    \"encoding/pem\"\n    \"os\"\n)\n\nfunc validPEMCABundle(path string) error {\n    b, err := os.ReadFile(path)\n    if err != nil { return err }\n    pool := x509.NewCertPool()\n    if !pool.AppendCertsFromPEM(b) {\n        return errors.New(\"file has no PEM CERTIFICATE blocks\")\n    }\n    if pem.Decode(b) == nil { return errors.New(\"not PEM-encoded\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"creds, err := expcreds.NewClientTLSFromFileWithALPNDisabled(path, sni)\nif err != nil { return fmt.Errorf(\"load CA bundle %s: %w\", path, err) }","preventionTips":["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."],"tags":["grpc","tls","pem","certificates","alpn","experimental"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}