{"record":{"id":"3e5f1975878526cd","repo":"Billionmail/BillionMail","slug":"failed-to-send-test-email-to-d-recipient-s-v","errorCode":null,"errorMessage":"failed to send test email to %d recipient(s): %v","messagePattern":"failed to send test email to (.+?) recipient\\(s\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/controller/settings/settings_v1_set_blacklist_alert_settings.go","lineNumber":155,"sourceCode":"\tvar failedRecipients []string\n\tfor _, recipient := range settings.RecipientList {\n\n\t\tmessage := mail_service.NewMessage(subject, body)\n\t\tmessage.SetRealName(settings.Name)\n\t\tmessageId := sender.GenerateMessageID()\n\t\tmessage.SetMessageID(messageId)\n\n\t\terr = sender.Send(message, []string{recipient})\n\t\tif err != nil {\n\t\t\tg.Log().Errorf(ctx, \"Failed to send test email to %s: %v\", recipient, err)\n\t\t\tfailedRecipients = append(failedRecipients, recipient)\n\t\t} else {\n\t\t\tg.Log().Infof(ctx, \"Test email sent successfully to %s\", recipient)\n\t\t}\n\t}\n\n\tif len(failedRecipients) > 0 {\n\t\treturn fmt.Errorf(\"failed to send test email to %d recipient(s): %v\", len(failedRecipients), failedRecipients)\n\t}\n\n\tg.Log().Infof(ctx, \"Test email sent successfully to all %d recipients\", len(settings.RecipientList))\n\treturn nil\n}\n\nfunc buildTestEmailHTML(settings *v1.SetBlacklistAlertSettingsReq) string {\n\treturn fmt.Sprintf(`\n<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>Alert Settings Configured Successfully</title>\n\t\t<style>\n\t\t\tp {\n\t\t\t\tmargin: 0;\n\t\t\t}","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/controller/settings/settings_v1_set_blacklist_alert_settings.go#L137-L173","documentation":"After attempting Send to each recipient, sendTestEmailWithMailService collects failures in failedRecipients; if any recipient failed it returns an error listing the count and the per-recipient errors. The connection succeeded but message delivery failed for one or more addresses.","triggerScenarios":"SetBlacklistAlertSettings test send where sender.Send returns an error for at least one address in RecipientList (rejected recipient, relay denied, mailbox nonexistent, rate limit).","commonSituations":"Recipient domain has no MX record; SMTP server rejects relaying for unauthenticated senders; sender email not allowed by the provider; typo'd recipient address.","solutions":["Check the wrapped recipient error list — it names each failed address and the SMTP rejection reason.","Remove/correct invalid recipient addresses and retry the test.","Ensure SenderEmail is a permitted From address on the SMTP account (spoofed-From rejection is common).","Verify the SMTP account is allowed to relay to external domains."],"exampleFix":"// before\nrecipientList: [\"admin@example.cm\"] // typo TLD, no MX\n// after\nrecipientList: [\"admin@example.com\"]","handlingStrategy":"try-catch","validationCode":"// validate every recipient's domain has MX before submitting\nfor (const r of recipientList) {\n  const domain = r.split('@')[1]\n  if (!domain || !(await hasMXRecord(domain))) throw new Error(`No MX for ${domain}: ${r}`)\n}","typeGuard":null,"tryCatchPattern":"err := SetBlacklistAlertSettings(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"failed to send test email to\") {\n  // parse failed recipients from the error, report per-address reasons in UI\n  var fe *FailedRecipientsError\n  if errors.As(err, &fe) { reportPerRecipient(fe.Recipients) }\n}","preventionTips":["Verify each recipient address/domain before saving","Ensure SenderEmail is an authorized From address on the SMTP account","Confirm the account may relay to external domains","Keep test sends to a small internal address list"],"tags":["smtp","email-delivery"],"backgroundTag":"email-send-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"}