{"record":{"id":"6b4253a7ef4bc4e4","repo":"amir20/dozzle","slug":"failed-to-read-certificates-w-6b4253","errorCode":null,"errorMessage":"failed to read certificates: %w","messagePattern":"failed to read certificates: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/support/cli/health_command.go","lineNumber":25,"sourceCode":"\t\"net\"\n\t\"os\"\n\n\t\"github.com/amir20/dozzle/internal/healthcheck\"\n\t\"github.com/rs/zerolog/log\"\n)\n\ntype HealthcheckCmd struct{}\n\nfunc (h *HealthcheckCmd) Run(args Args, embeddedCerts embed.FS) error {\n\tconst agentAddrFile = \"/tmp/dozzle-agent.addr\"\n\tif data, err := os.ReadFile(agentAddrFile); err == nil {\n\t\tagentAddress := string(data)\n\t\tif host, port, err := net.SplitHostPort(agentAddress); err == nil && (host == \"\" || host == \"::\" || host == \"0.0.0.0\") {\n\t\t\tagentAddress = \"127.0.0.1:\" + port\n\t\t}\n\t\tcerts, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read certificates: %w\", err)\n\t\t}\n\t\tctx, cancel := context.WithTimeout(context.Background(), args.Timeout)\n\t\tdefer cancel()\n\t\tlog.Info().Str(\"address\", agentAddress).Msg(\"Making RPC request to agent\")\n\t\treturn healthcheck.RPCRequest(ctx, agentAddress, certs)\n\t} else {\n\t\tlog.Info().Str(\"address\", args.Addr).Str(\"base\", args.Base).Msg(\"Making HTTP request to server\")\n\t\treturn healthcheck.HttpRequest(args.Addr, args.Base)\n\t}\n}\n","sourceCodeStart":7,"sourceCodeEnd":36,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/support/cli/health_command.go#L7-L36","documentation":"The `dozzle healthcheck` command, when an agent address file exists, loads TLS certificates via ReadCertificates (embedded + provided cert/key paths) before making an RPC request to the agent. If the cert files cannot be read or parsed, the error is wrapped as 'failed to read certificates'.","triggerScenarios":"Running `dozzle healthcheck` with --cert-file/--key-file paths that don't exist, are unreadable (permissions), or contain invalid PEM data; missing mounted certificates in the container.","commonSituations":"Docker deployments where shared_cert.pem/shared_key.pem are not mounted at the expected path; stale cert paths after volume changes; corrupted or empty cert files.","solutions":["Verify the cert and key file paths passed to the command exist and are readable","Re-run `make generate` (or recreate the container) to regenerate shared certs and mount them correctly","Check file permissions so the dozzle process user can read both files","Validate the files contain valid PEM certificates"],"exampleFix":"// before\ndocker run ... -v ./certs:/certs dozzle healthcheck --cert-file /wrong/cert.pem --key-file /wrong/key.pem\n// after\ndocker run ... -v ./certs:/certs dozzle healthcheck --cert-file /certs/shared_cert.pem --key-file /certs/shared_key.pem","handlingStrategy":"validation","validationCode":"for f in \"$CERT\" \"$KEY\"; do\n  [ -r \"$f\" ] || { echo \"missing/unreadable cert file: $f\" >&2; exit 1; }\n  openssl x509 -in \"$CERT\" -noout >/dev/null 2>&1 || { echo 'invalid PEM cert' >&2; exit 1; }\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mount shared_cert.pem/shared_key.pem at consistent paths and pass matching --cert-file/--key-file","Regenerate certs with make generate after regeneration events","Check file permissions for the process user before running healthcheck"],"tags":["tls","certificates","cli"],"backgroundTag":"file-not-found","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}