{"record":{"id":"7eb6d173e4638223","repo":"Billionmail/BillionMail","slug":"smtp-data-w","errorCode":null,"errorMessage":"SMTP data: %w","messagePattern":"SMTP data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/mail_service/sending.go","lineNumber":429,"sourceCode":"\t// Set the sender\n\t// MAIL FROM\n\tif err = e.client.Mail(e.Email); err != nil {\n\t\treturn fmt.Errorf(\"SMTP mail: %w\", err)\n\t}\n\n\t// Set the recipients\n\t// RCPT TO\n\tfor _, to := range recipients {\n\t\tif err = e.client.Rcpt(to); err != nil {\n\t\t\treturn fmt.Errorf(\"SMTP rcpt: %w\", err)\n\t\t}\n\t}\n\n\t// Get a writer for the message body\n\tvar w io.WriteCloser\n\tw, err = e.client.Data()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"SMTP data: %w\", err)\n\t}\n\n\t// Write the message\n\tif _, err = w.Write(msg); err != nil {\n\t\treturn fmt.Errorf(\"SMTP write: %w\", err)\n\t}\n\n\t// Close the writer\n\tif err = w.Close(); err != nil {\n\t\treturn fmt.Errorf(\"SMTP close writer: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// isSecure check if TLS connection is needed\nfunc (e *EmailSender) isSecure() bool {\n\t// usually,","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/mail_service/sending.go#L411-L447","documentation":"This error wraps a failure of net/smtp Client.Data(), which issues the SMTP DATA command. The server refused to enter data mode (usually a 4xx/5xx reply) after envelope sender and recipients were accepted. No message body was transmitted.","triggerScenarios":"e.client.Data() returned an error — commonly a '554 transaction failed' reply, a connection that dropped after RCPT TO, or the server rejecting the transaction due to policy (spam filter, greylisting) between RCPT and DATA.","commonSituations":"Postfix smtpd bans or throttles the client after the envelope; connection idle-timed out mid-transaction; rspamd/milter rejects the transaction at DATA stage; network interruption during the SMTP session.","solutions":["Check mail server logs for the reply code returned at DATA to identify policy rejection vs connection issue","Retry with a fresh SMTP connection — the session may be stale; the deferred Reset() already attempts to clear state","If a milter (rspamd) rejects at DATA, inspect milter settings and message headers triggering the rejection","Ensure keepalives/short transaction times so the connection doesn't idle out between commands"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if sender == nil || !connectionHealthy() {\n    return errors.New(\"SMTP session not ready for DATA\")\n}","typeGuard":null,"tryCatchPattern":"err := sender.Send(msg, recipients)\nif err != nil {\n    if isTransient(err) { // 4xx or io.EOF\n        backoffRetry(3)\n    } else {\n        logAndFail(err)\n    }\n}","preventionTips":["Re-establish the SMTP connection instead of reusing long-idle sessions","Check mail server milter/policy settings if DATA rejections are frequent","Monitor mail logs for greylisting/throttling and add retry with backoff","Keep transaction duration short to avoid server-side timeouts"],"tags":["smtp","data-command","email-delivery"],"backgroundTag":"smtp-transaction-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}