{"record":{"id":"50eb7c52cf4b4ad3","repo":"JuliusBrussee/caveman","slug":"s-w","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/chhttp/chhttp.go","lineNumber":163,"sourceCode":"\treturn cfg, nil\n}\n\n// rootsWithCAFile returns the system pool with the PEM bundle at path appended.\n// Appending (rather than replacing) keeps a public managed endpoint verifiable\n// while a private CA is trusted for the internal one.\n//\n// The bundle is parsed block by block instead of via CertPool.AppendCertsFromPEM,\n// which reports success as soon as ONE certificate parses and silently drops the\n// rest. A secret mount that is truncated mid-bundle, or corrupt after the first\n// entry, would then be half-trusted: the endpoints whose issuer survived keep\n// verifying and the ones whose issuer was dropped fail later, at the first\n// telemetry flush, looking like a network fault. Any unusable certificate block —\n// or a trailing PEM header with no complete block behind it — fails the whole\n// bundle CLOSED at boot instead.\nfunc rootsWithCAFile(path string) (*x509.CertPool, error) {\n\tbundle, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s: %w\", caFileEnv, err)\n\t}\n\troots, err := x509.SystemCertPool()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s: load system certificate pool: %w\", caFileEnv, err)\n\t}\n\tadded := 0\n\trest := bundle\n\tfor {\n\t\tvar block *pem.Block\n\t\tblock, rest = pem.Decode(rest)\n\t\tif block == nil {\n\t\t\tbreak\n\t\t}\n\t\tif block.Type != \"CERTIFICATE\" {\n\t\t\tcontinue\n\t\t}\n\t\tcert, err := x509.ParseCertificate(block.Bytes)\n\t\tif err != nil {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/shared/platform/chhttp/chhttp.go#L145-L181","documentation":"Thrown by rootsWithCAFile when os.ReadFile fails on the path in CLICKHOUSE_TLS_CA_FILE; the underlying error (no such file, permission denied, etc.) is wrapped with the env var name for context. The ClickHouse TLS config fails closed — an unreadable CA bundle is an error, never a silent fallback to the ambient trust store.","triggerScenarios":"Setting CLICKHOUSE_TLS_CA_FILE to a path that doesn't exist in the container, isn't mounted yet, or has restrictive permissions; a trailing newline/whitespace or quotes around the path in the env value can also produce a non-existent path.","commonSituations":"Secret not mounted at the expected path in k8s (volume mount name/path mismatch); running the binary locally with a path from the deploy manifest; a rotated secret whose new file path differs; env value copied with surrounding quotes.","solutions":["Check the wrapped os.ReadFile error: 'no such file or directory' means fix the path/mount, 'permission denied' means fix file ownership/mode.","Verify the mount exists at process start: in k8s confirm the volume is mounted and the secret key produces that filename; locally, ls the exact path.","Ensure the env value has no surrounding quotes or stray whitespace (the code trims spaces, but shell quoting can still bite depending on how env is injected).","If you meant to drop custom CAs and use system roots, unset CLICKHOUSE_TLS_CA_FILE entirely."],"exampleFix":"# before\nCLICKHOUSE_TLS_CA_FILE=/etc/clickhouse/ca.pem   # secret mounted elsewhere\n\n# after — match the actual mount path\nCLICKHOUSE_TLS_CA_FILE=/etc/secrets/clickhouse/ca.pem\n# kustomization: verify volumes[].mountPath and the secret key filename line up","handlingStrategy":"validation","validationCode":"if p := os.Getenv(\"CLICKHOUSE_TLS_CA_FILE\"); p != \"\" {\n    if _, err := os.Stat(p); err != nil {\n        return fmt.Errorf(\"CLICKHOUSE_TLS_CA_FILE %q is not readable before start: %w\", p, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"Handle at startup: read the wrapped os.ReadFile error, fix the mount/path/permissions, and restart. Do not catch and fall back to system roots — that fallback is exactly what the fail-closed design forbids.","preventionTips":["Verify the secret mount path in the container matches the env var (mountPath + secret key filename).","Add a startup readiness probe that stats the CA file.","Keep file permissions readable by the service account (e.g. 0644 on the mounted secret)."],"tags":["clickhouse","tls","configuration","file-io","secrets"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}