{"record":{"id":"75ae9500dcb3f5ac","repo":"Billionmail/BillionMail","slug":"failed-to-restart-postfix-container-v-75ae95","errorCode":null,"errorMessage":"failed to restart postfix container: %v","messagePattern":"failed to restart postfix container: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/mail_service/certificate.go","lineNumber":447,"sourceCode":"\n// updateConfigLine updates a configuration line in config file\nfunc (c *Certificate) updateConfigLine(config, key, value string) string {\n\tlines := strings.Split(config, \"\\n\")\n\tfor i, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\t\tif strings.HasPrefix(line, key) && strings.Contains(line, \"=\") {\n\t\t\tlines[i] = key + \" = \" + value\n\t\t\treturn strings.Join(lines, \"\\n\")\n\t\t}\n\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","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/mail_service/certificate.go#L429-L465","documentation":"restartPostfix asks the Docker API client to restart the Postfix container (consts.SERVICES.Postfix) so new SSL settings take effect. Any Docker-level restart failure is wrapped as 'failed to restart postfix container: %v'. Thrown by SetSSL, SetSNI, SetPostfixSSL and SetPostfixVMailCert — i.e. the cert files and configs were updated but the service was not reloaded.","triggerScenarios":"Any of SetSSL/SetSNI/SetPostfixSSL/SetPostfixVMailCert called when the Postfix container is not running, has a different name than consts.SERVICES.Postfix, or the Docker socket/daemon is unreachable.","commonSituations":"Docker socket not mounted (/var/run/docker.sock missing or permission denied); Postfix runs on the host instead of a container; container renamed after a compose refactor; Docker daemon restarting or out of memory.","solutions":["Verify the Postfix container exists and matches consts.SERVICES.Postfix (docker ps) and rename/recreate it if needed","Ensure the Docker socket is mounted and accessible (docker.sock volume, root or docker group)","Start the Postfix container if it is stopped (docker compose up -d postfix)","Manually restart postfix (docker restart <postfix>) to apply the new certs, then retry the API call"],"exampleFix":"// before\nif err := c.dockerApiClient().RestartContainerByName(context.Background(), consts.SERVICES.Postfix); err != nil {\n    return fmt.Errorf(\"failed to restart postfix container: %v\", err)\n}\n// after\nif err := c.dockerApiClient().RestartContainerByName(context.Background(), consts.SERVICES.Postfix); err != nil {\n    // config files are already updated; surface actionable guidance\n    return fmt.Errorf(\"failed to restart postfix container %s (is it running? is docker.sock mounted?): %w\", consts.SERVICES.Postfix, err)\n}","handlingStrategy":"retry","validationCode":"cli, err := c.dockerApiClient().ContainerList(ctx, types.ContainerListOptions{All: true})\nif err != nil {\n    return fmt.Errorf(\"docker unreachable: %w\", err)\n}\nrunning := false\nfor _, ct := range cli {\n    if strings.Contains(strings.Join(ct.Names, \",\"), consts.SERVICES.Postfix) {\n        running = true\n    }\n}\nif !running {\n    return fmt.Errorf(\"postfix container %s not running\", consts.SERVICES.Postfix)\n}","typeGuard":null,"tryCatchPattern":"if err := certSvc.SetSSL(ctx, domain); err != nil {\n    if strings.Contains(err.Error(), \"failed to restart postfix container\") {\n        // check docker.sock mount, container name, then retry or restart manually\n    }\n    return err\n}","preventionTips":["Ensure /var/run/docker.sock is mounted and accessible where this code runs","Keep the compose service name in sync with consts.SERVICES.Postfix","Add a startup health check that the postfix container is up before cert operations","Retry the restart with backoff to tolerate transient Docker daemon hiccups"],"tags":["docker","postfix","container","service-restart"],"backgroundTag":"docker-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"}