{"record":{"id":"e6d4eba280f604d2","repo":"gofiber/fiber","slug":"failed-to-append-certificate","errorCode":null,"errorMessage":"failed to append certificate","messagePattern":"failed to append certificate","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"client/client.go","lineNumber":34,"sourceCode":"\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"slices\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/fxamacker/cbor/v2\"\n\t\"github.com/gofiber/fiber/v3/log\"\n\n\t\"github.com/gofiber/utils/v2\"\n\n\t\"github.com/valyala/fasthttp\"\n\t\"github.com/valyala/fasthttp/fasthttpproxy\"\n\t\"golang.org/x/net/http/httpproxy\"\n)\n\nvar ErrFailedToAppendCert = errors.New(\"failed to append certificate\")\n\n// Client provides Fiber's high-level HTTP API while delegating transport work\n// to fasthttp.Client, fasthttp.HostClient, or fasthttp.LBClient implementations.\n//\n// Settings configured on the client are shared across every request and may be\n// overridden per request when needed.\n// Client is safe for concurrent request execution after configuration is\n// complete. Concurrent configuration changes require external synchronization.\ntype Client struct {\n\tlogger    log.CommonLogger\n\ttransport httpClientTransport\n\n\theader  *Header\n\tparams  *QueryParam\n\tcookies *Cookie\n\tpath    *PathParam\n\n\tjsonMarshal   utils.JSONMarshal","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/client/client.go#L16-L52","documentation":"Wraps the failure returned by tls.Config.RootCAs.AppendCertsFromPEM inside Client.SetRootCertificate (client/client.go:336) and SetRootCertificateFromString (client/client.go:351). AppendCertsFromPEM returns false when the PEM bytes contain no parseable certificate blocks; Fiber turns that into a logger.Panicf, terminating the program because client configuration is unrecoverable.","triggerScenarios":"Calling client.SetRootCertificate(path) where the file is not valid PEM, contains only a private key, has a corrupted BEGIN/END block, or is empty; calling SetRootCertificateFromString(pem) with the contents of a CSR, a DER blob, or a typo-pasted bundle.","commonSituations":"Pointing SetRootCertificate at a certificate in DER instead of PEM format; passing a fullchain that includes non-certificate sections; copy/paste truncating the END line; reading a key file by mistake.","solutions":["Verify the file is PEM-encoded: it must have '-----BEGIN CERTIFICATE-----' / '-----END CERTIFICATE-----' blocks. Convert DER with: openssl x509 -inform DER -in cert.der -out cert.pem -outform PEM.","Inspect the file before passing it; ensure at least one CERTIFICATE block is present.","Load and AppendCertsFromPEM in your own code first to get a real error rather than the panic, then assign tls.Config directly.","If you must keep the panic behavior, gate the call behind a build/runtime check so misconfiguration surfaces at startup, not mid-request."],"exampleFix":"// before\nclient.SetRootCertificate(\"/etc/secrets/ca.der\") // ErrFailedToAppendCert panic\n\n// after\n// convert once: openssl x509 -inform DER -in ca.der -out ca.pem -outform PEM\nclient.SetRootCertificate(\"/etc/secrets/ca.pem\")","handlingStrategy":"validation","validationCode":"// Validate the PEM in your own code to get a real error before the panic\nfunc mustAppendCAs(pool *x509.CertPool, pem []byte) error {\n    if !pool.AppendCertsFromPEM(pem) {\n        return errors.New(\"PEM contained no parseable certificate\")\n    }\n    return nil\n}\n// call this before client.SetRootCertificateFromString(string(pem))","typeGuard":"func looksLikePEMCert(pem []byte) bool {\n    return bytes.Contains(pem, []byte(\"-----BEGIN CERTIFICATE-----\")) &&\n        bytes.Contains(pem, []byte(\"-----END CERTIFICATE-----\"))\n}","tryCatchPattern":"// SetRootCertificate panics, so wrap setup in recover if you want graceful failure:\nfunc safeSetRootCert(c *fiber.Client, path string) (err error) {\n    defer func() {\n        if r := recover(); r != nil { err = fmt.Errorf(\"%v\", r) }\n    }()\n    c.SetRootCertificate(path)\n    return nil\n}","preventionTips":["Always provide PEM-encoded CA bundles, never DER.","Inspect the file with openssl x509 -in ca.pem -noout before pointing the client at it.","Gate TLS setup at program start so a misconfiguration fails fast, not mid-request."],"tags":["tls","certificates","client","pem","panic"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}