amir20/dozzle · error
failed to read certificates
Error message
failed to read certificates: %w
What it means
Returned by AgentCmd.Run when ReadCertificates fails to load the embedded or on-disk TLS certificate/key pair the gRPC agent requires. Agents and main servers authenticate each other with these shared certs, so startup aborts without them.
Solutions
- Remove custom --cert-path/--key-path flags so the embedded certs are used.
- If custom certs are required, verify both files exist, are valid PEM, and match as a pair.
- Regenerate the shared certs: `make generate`.
- Check file permissions on the cert and key files.
- Ensure the agent and main server share the same certificate pair.
Example fix
// before customCert=/etc/dozzle/old-cert.pem --cert-path $customCert --key-path /etc/dozzle/old-key.pem // after rm -f /etc/dozzle/old-*.pem make generate # or drop the custom cert flags entirely
Defensive patterns
Strategy: validation
Validate before calling
for f in "$CERT" "$KEY"; do [ -r "$f" ] && openssl "$([ "${f##*.}" = key ] && echo rsa || echo x509)" -in "$f" -noout >/dev/null || { echo "bad cert file: $f"; exit 1; }; done Try / catch
if err := agentCmd.Run(args, embeddedCerts); err != nil {
if strings.Contains(err.Error(), "failed to read certificates") {
log.Fatal().Err(err).Msg("check --cert-path/--key-path files")
}
} Prevention
- Regenerate and deploy cert/key pairs together with `make generate`
- Validate PEM files with openssl before use
- Prefer embedded certs over custom paths when possible
- Verify file readability for the process user
When it happens
Trigger: Custom --cert-path/--key-path files are missing, unreadable, or malformed PEM; key does not match certificate; certificates were not regenerated after a version upgrade (make generate).
Common situations: User overrides cert paths with files from an old install; cert/key mismatch after regenerating only one; file permissions block reading the PEM files; running a custom build without running `make generate`.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to parse certificate
- failed to parse certificate
- failed to create agent server
- error reading certificates
- failed to read certificates
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/d7ed2c953ab7ece0.
Report an issue: GitHub.
Appendix: source
Thrown at internal/support/cli/agent_command.go:151
if h.onCloudSet != nil {
h.onCloudSet()
}
if err := os.Remove("./data/cloud.yml"); err != nil && !os.IsNotExist(err) {
log.Error().Err(err).Msg("Could not remove cloud.yml on agent")
}
}
func (a *AgentCmd) Run(args Args, embeddedCerts embed.FS) error {
if args.Mode != "server" {
return fmt.Errorf("agent command is only available in server mode")
}
client, err := docker.NewLocalClient(args.Hostname)
if err != nil {
return fmt.Errorf("failed to create docker client: %w", err)
}
certs, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)
if err != nil {
return fmt.Errorf("failed to read certificates: %w", err)
}
listener, err := net.Listen("tcp", args.Agent.Addr)
if err != nil {
return fmt.Errorf("failed to listen: %w", err)
}
const agentAddrFile = "/tmp/dozzle-agent.addr"
if err := os.WriteFile(agentAddrFile, []byte(args.Agent.Addr), 0644); err != nil {
return fmt.Errorf("failed to write agent address file: %w", err)
}
go StartEvent(args, "", client, "agent")
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
// Create shared client service (single ContainerStore for both agent server and notifications)
clientService := docker_support.NewDockerClientService(client, args.Filter)
View on GitHub (pinned to d9463cbe21)