{"record":{"id":"50c99fa98a7a932e","repo":"Billionmail/BillionMail","slug":"failed-to-restart-dovecot-container-v","errorCode":null,"errorMessage":"failed to restart dovecot container: %v","messagePattern":"failed to restart dovecot container: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/mail_service/certificate.go","lineNumber":457,"sourceCode":"\t}\n\treturn config + \"\\n\" + key + \" = \" + value\n}\n\n// restartPostfix restarts Postfix service\nfunc (c *Certificate) restartPostfix() error {\n\t// Restart Postfix container\n\tif err := c.dockerApiClient().RestartContainerByName(context.Background(), consts.SERVICES.Postfix); err != nil {\n\t\treturn fmt.Errorf(\"failed to restart postfix container: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// restartDovecot restarts Dovecot service\nfunc (c *Certificate) restartDovecot() error {\n\t// Restart Dovecot container\n\tif err := c.dockerApiClient().RestartContainerByName(context.Background(), consts.SERVICES.Dovecot); err != nil {\n\t\treturn fmt.Errorf(\"failed to restart dovecot container: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// GetSSLStatus checks SSL certificate status\nfunc (c *Certificate) GetSSLStatus(domain string) (bool, error) {\n\t// Check Postfix certificate\n\tcsrPath := filepath.Join(consts.SSL_PATH, domain, \"/fullchain.pem\")\n\tketPath := filepath.Join(consts.SSL_PATH, domain, \"/privkey.pem\")\n\n\treturn c.checkCertificateFiles(csrPath, ketPath), nil\n}\n\n// GetSSLInfo retrieves SSL certificate information\nfunc (c *Certificate) GetSSLInfo(domain string) (certInfo v1.CertInfo, err error) {\n\t// First try to get certificate from database (acme managed certificates)\n","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/mail_service/certificate.go#L439-L475","documentation":"restartDovecot wraps any failure from the Docker API call that restarts the Dovecot container (consts.SERVICES.Dovecot). The underlying Docker error (container missing, daemon unreachable, API timeout) is preserved via %v. Callers SetSSL, SetSNI and SetDovecotSSL surface it when certificate/SNI changes require the mail service to reload.","triggerScenarios":"Calling SetSSL, SetSNI, or SetDovecotSSL when the Docker daemon is down, the dovecot container does not exist (never started, renamed, or removed), or RestartContainerByName times out.","commonSituations":"Deploying on a host where the container is named differently than consts.SERVICES.Dovecot expects; Docker daemon restarted/not running; resource exhaustion making the restart hang; docker socket permission denied for the BillionMail process.","solutions":["Verify the dovecot container is running: `docker ps | grep dovecot`; start it if missing (`docker compose up -d dovecot`).","Check Docker daemon health and that the API client's endpoint/socket is reachable (`docker info`, socket permissions).","Confirm consts.SERVICES.Dovecot matches the actual container name in your deployment.","Retry SetSSL/SetSNI after the container is healthy; check underlying %v detail for the specific Docker error."],"exampleFix":"// before\ncertInfo, err := GetSSLInfo(ctx)\nif err != nil { log.Fatal(err) }\n// after\ncertInfo, err := GetSSLInfo(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to restart dovecot container\") {\n        log.Printf(\"dovecot restart failed, check docker: %v\", err)\n    }\n    log.Fatal(err)\n}","handlingStrategy":"retry","validationCode":"out, err := exec.Command(\"docker\", \"ps\", \"--format\", \"{{.Names}}\").Output()\nif err != nil || !strings.Contains(string(out), \"dovecot\") {\n    return errors.New(\"dovecot container not running; start it before changing SSL settings\")\n}","typeGuard":null,"tryCatchPattern":"err := cert.SetSSL(ctx, domain, certPem, keyPem)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to restart dovecot container\") {\n        time.Sleep(5 * time.Second)\n        err = cert.SetSSL(ctx, domain, certPem, keyPem) // bounded retry\n    }\n    return err\n}","preventionTips":["Monitor Docker daemon health before applying SSL changes.","Pin container names to consts.SERVICES values in deployment config.","Run the app with docker socket access (group membership or root)."],"tags":["docker","container","dovecot","mail-service"],"backgroundTag":"container-restart-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}