{"record":{"id":"677d184490ee4be4","repo":"grpc/grpc-go","slug":"credentials-failed-to-append-certificates","errorCode":null,"errorMessage":"credentials: failed to append certificates","messagePattern":"credentials: failed to append certificates","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/tls.go","lineNumber":290,"sourceCode":"\n// NewClientTLSFromFile constructs TLS credentials from the provided root\n// certificate authority certificate file(s) to validate server connections. If\n// certificates to establish the identity of the client need to be included in\n// the credentials (eg: for mTLS), use NewTLS instead, where a complete\n// tls.Config can be specified.\n//\n// serverNameOverride is for testing only. If set to a non empty string, it will\n// override the virtual host name of authority (e.g. :authority header field) in\n// requests.  Users should use grpc.WithAuthority passed to grpc.NewClient to\n// override the authority of the client instead.\nfunc NewClientTLSFromFile(certFile, serverNameOverride string) (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 NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil\n}\n\n// NewServerTLSFromCert constructs TLS credentials from the input certificate for server.\nfunc NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials {\n\treturn NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}})\n}\n\n// NewServerTLSFromFile constructs TLS credentials from the input certificate file and key\n// file for server.\nfunc NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) {\n\tcert, err := tls.LoadX509KeyPair(certFile, keyFile)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}}), nil\n}","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/tls.go#L272-L308","documentation":"Returned by NewClientTLSFromFile in credentials/tls.go:290 when x509.CertPool.AppendCertsFromPEM returns false, meaning the file contents were not parseable as one or more PEM-encoded certificates. The file was readable (os.ReadFile succeeded) but the bytes are not a valid PEM cert block — e.g. a DER blob, a key file, or a non-cert PEM block.","triggerScenarios":"Passing a path to NewClientTLSFromFile whose content is a DER-encoded cert, a private key, a certificate chain in the wrong encoding, a CA bundle with extra text, or an empty file.","commonSituations":"Using the server key/cert file instead of the CA cert; cert generated as DER (openssl enc -outform DER) instead of PEM; pasting only the human-readable text of a PEM; an empty or truncated file from a failed download.","solutions":["Regenerate/obtain the certificate in PEM format (openssl x509 -inform DER -outform PEM -in cert.der -out cert.pem).","Pass the CA certificate file (-----BEGIN CERTIFICATE-----), not the private key, to NewClientTLSFromFile.","For a full tls.Config including client certs, use credentials.NewTLS with a populated tls.Config instead."],"exampleFix":"// before\ncreds, err := credentials.NewClientTLSFromFile(\"/etc/certs/server.key\", \"svc\") // wrong file\n\n// after\ncreds, err := credentials.NewClientTLSFromFile(\"/etc/certs/ca.pem\", \"svc.example.com\")","handlingStrategy":"validation","validationCode":"b, err := os.ReadFile(certFile)\nif err != nil { return err }\npool := x509.NewCertPool()\nif !pool.AppendCertsFromPEM(b) {\n    // likely DER or a non-cert PEM block; convert first\n    return errors.New(\"not PEM; convert with: openssl x509 -inform DER -outform PEM\")\n}\ncreds := credentials.NewClientTLSFromCert(pool, serverName)","typeGuard":"func isPEMCert(b []byte) bool {\n    return bytes.Contains(b, []byte(\"-----BEGIN CERTIFICATE-----\"))\n}","tryCatchPattern":"creds, err := credentials.NewClientTLSFromFile(certFile, serverName)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to append certificates\") {\n        // file is not PEM certs; convert DER->PEM or point at the CA cert file\n    }\n    return err\n}","preventionTips":["Keep CA certs in PEM (-----BEGIN CERTIFICATE-----) form, not DER.","Do not pass private-key files to NewClientTLSFromFile.","For client-cert mTLS, use credentials.NewTLS with a full tls.Config."],"tags":["tls","certificates","configuration","file-io","go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}