{"record":{"id":"5aadad62d64dce01","repo":"temporalio/temporal","slug":"unable-to-decode-client-ca-data","errorCode":null,"errorMessage":"unable to decode client ca data","messagePattern":"unable to decode client ca data","errorType":"validation","errorClass":"ErrTLSConfig","httpStatus":null,"severity":"error","filePath":"common/auth/tls_config_helper.go","lineNumber":151,"sourceCode":"\n\tif temporalTls.CaData != \"\" && temporalTls.CaFile != \"\" {\n\t\treturn fmt.Errorf(\"%w: %s\", ErrTLSConfig, \"only one of caData or caFile properties should be specified\")\n\t}\n\treturn nil\n}\n\nfunc parseCAs(temporalTls *TLS) (*x509.CertPool, error) {\n\tvar caBytes []byte\n\tvar err error\n\tif temporalTls.CaFile != \"\" {\n\t\tcaBytes, err = os.ReadFile(temporalTls.CaFile)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: %s (%w)\", ErrTLSConfig, \"unable to read client ca file\", err)\n\t\t}\n\t} else if temporalTls.CaData != \"\" {\n\t\tcaBytes, err = base64.StdEncoding.DecodeString(temporalTls.CaData)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: %s (%w)\", ErrTLSConfig, \"unable to decode client ca data\", err)\n\t\t}\n\t}\n\tif len(caBytes) > 0 {\n\t\tcaCertPool := x509.NewCertPool()\n\t\tcaCerts, err := parseCertsFromPEM(caBytes)\n\t\tif len(caCerts) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"%w: %s (%w)\", ErrTLSConfig, \"unable to parse certs as PEM\", err)\n\t\t}\n\t\tfor _, cert := range caCerts {\n\t\t\tcaCertPool.AddCert(cert)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: %s (%w)\", ErrTLSConfig, \"unable to load decoded CA Cert as PEM\", err)\n\t\t}\n\t\treturn caCertPool, nil\n\t}\n\treturn nil, nil\n}","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/auth/tls_config_helper.go#L133-L169","documentation":"parseCAs returns this error when CaData is set but base64.StdEncoding.DecodeString fails, meaning the value is not valid base64 (invalid characters, wrong padding, or a raw PEM pasted without encoding). The decode error is chained and wrapped with ErrTLSConfig.","triggerScenarios":"NewTLSConfig -> parseCAs with CaData containing non-base64 text — e.g. a PEM block pasted verbatim, a base64 string with newlines/whitespace handled incorrectly, or truncated data.","commonSituations":"Pasting certificate content directly into YAML instead of base64-encoding it; editors/tools adding line breaks that break decoding depending on how config is parsed; double-encoding (base64 of base64) leaving stray characters; quoting/escaping issues in templated config.","solutions":["Re-encode the CA PEM with: base64 -w0 ca.pem (single-line, no newlines) and use that exact string for CaData.","Confirm you are not double-encoding: the value must decode once to PEM text beginning with -----BEGIN CERTIFICATE-----.","Strip surrounding whitespace/quotes or YAML multiline issues that corrupt the base64 string.","Alternatively switch to CaFile pointing at the PEM on disk to avoid encoding entirely."],"exampleFix":"// before\ntls:\n  caData: \"-----BEGIN CERTIFICATE-----\\nMIID...\"   # raw PEM, not base64\n// after\ntls:\n  caData: \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ...\" # base64 -w0 ca.pem","handlingStrategy":"validation","validationCode":"func checkCaDataIsBase64(caData string) error {\n\tdecoded, err := base64.StdEncoding.DecodeString(caData)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"caData is not valid base64: %w\", err)\n\t}\n\tif !strings.Contains(string(decoded), \"BEGIN CERTIFICATE\") {\n\t\treturn fmt.Errorf(\"caData does not decode to PEM certificate\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate inline values only via base64 -w0 file.pem (single line, no wrapping)","Never paste raw PEM into *Data fields","If your config format inserts newlines, use caFile instead of caData","Verify decoded content locally before deploy: echo '<value>' | base64 -d | openssl x509 -noout -subject"],"tags":["tls","config","encoding","base64"],"backgroundTag":"invalid-base64","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}