{"record":{"id":"007d367f2378c2ba","repo":"gofr-dev/gofr","slug":"failed-to-append-ca-certificate","errorCode":null,"errorMessage":"failed to append CA certificate","messagePattern":"failed to append CA certificate","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/datasource/sql/sql.go","lineNumber":40,"sourceCode":")\n\nconst (\n\tsqlite            = \"sqlite\"\n\tcockroachDB       = \"cockroachdb\"\n\tdefaultDBPort     = 3306\n\trequireSSLMode    = \"require\"\n\ttlsSkipVerify     = \"tls=skip-verify\"\n\tsslModeDisable    = \"disable\"\n\tsslModeVerifyCA   = \"verify-ca\"\n\tsslModeVerifyFull = \"verify-full\"\n\ttlsCustom         = \"tls=custom\"\n\tlocalhost         = \"localhost\"\n)\n\nvar (\n\terrUnsupportedDialect = fmt.Errorf(\n\t\t\"unsupported db dialect; supported dialects are - mysql, postgres, supabase, sqlite, %s\", cockroachDB)\n\terrFailedCACerts = fmt.Errorf(\"failed to append CA certificate\")\n)\n\n// DBConfig has those members which are necessary variables while connecting to database.\ntype DBConfig struct {\n\tDialect     string\n\tHostName    string\n\tUser        string\n\tPassword    string\n\tPort        string\n\tDatabase    string\n\tSSLMode     string\n\tMaxIdleConn int\n\tMaxOpenConn int\n\tCharset     string\n}\n\n// redactedPassword is the fixed mask substituted for a non-empty password whenever\n// a DBConfig is stringified, so the raw secret is never printed.","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/sql/sql.go#L22-L58","documentation":"errFailedCACerts is a sentinel returned by registerMySQLTLSConfig when the CA certificate file was read but its PEM contents could not be parsed into an x509 cert pool (AppendCertsFromPEM returned false). gofr wraps it as \"failed to append CA certificate\". It means the custom TLS trust configuration for MySQL is invalid.","triggerScenarios":"Calling NewSQL for a mysql dialect with DB_TLS_CA_CERT_PATH set to a file that is not a valid PEM-encoded certificate, an empty file, or a file containing DER-encoded or corrupted cert data.","commonSituations":"Pointing DB_TLS_CA_CERT_PATH at a key file, an intermediate bundle with unexpected encoding, or a truncated download; mounting a Kubernetes secret with the wrong key; using a cert chain where none of the PEM blocks parse.","solutions":["Verify the CA file contains valid PEM blocks (-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----).","Re-export or re-download the CA certificate in PEM format (openssl x509 -in ca.crt -out ca.pem).","Check the DB_TLS_CA_CERT_PATH env var points to the CA file, not the client key or a DER bundle.","Confirm the mounted file is non-empty and not truncated."],"exampleFix":"// before (DER-encoded file passed as CA)\nos.Setenv(\"DB_TLS_CA_CERT_PATH\", \"/certs/ca.der\")\n// after\nos.Setenv(\"DB_TLS_CA_CERT_PATH\", \"/certs/ca.pem\") // valid PEM CA bundle","handlingStrategy":"validation","validationCode":"pem, err := os.ReadFile(os.Getenv(\"DB_TLS_CA_CERT_PATH\"))\nif err != nil { return err }\nif !x509.NewCertPool().AppendCertsFromPEM(pem) {\n    return errors.New(\"CA file is not valid PEM\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate CA PEM files at deploy time (openssl x509 -in ca.pem -noout).","Mount certs read-only and verify checksums in CI.","Never point DB_TLS_CA_CERT_PATH at key files or DER exports."],"tags":["tls","mysql","certificates","configuration"],"backgroundTag":"invalid-ca-certificate","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}