apache/seatunnel · error · EmailConnectorException
SEND_EMAIL_FAILED
SEND_EMAIL_FAILED
Error message
Send email failed
What it means
EmailSinkWriter.close() triggers sending of the composed MIME message via Transport.send(message). If the SMTP send fails for any reason (connectivity, authentication, protocol errors), the exception is wrapped in an EmailConnectorException with error code SEND_EMAIL_FAILED and the message "Send email failed".
Source
Thrown at seatunnel-connectors-v2/connector-email/src/main/java/org/apache/seatunnel/connectors/seatunnel/email/sink/EmailSinkWriter.java:167
// Create multiple messages
Multipart multipart = new MimeMultipart();
// Set up the text message section
multipart.addBodyPart(messageBodyPart);
// accessory
messageBodyPart = new MimeBodyPart();
String filename = config.getEmailAttachmentName();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
// send a message
Transport.send(message);
log.info("Sent message successfully....");
} catch (Exception e) {
throw new EmailConnectorException(
EmailConnectorErrorCode.SEND_EMAIL_FAILED, "Send email failed", e);
}
}
public void createFile() {
String fileName = config.getEmailAttachmentName();
try {
String data = stringBuffer.toString();
File file = new File(fileName);
// if file doesn't exist, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file.getName());
fileWriter.write(data);
fileWriter.close();
log.info("Create File successfully....");
} catch (IOException e) {View on GitHub (pinned to cf67b549a7)
Solutions
- Verify SMTP configuration (host, port, auth, SSL/TLS settings) against your mail provider's documented settings.
- Test SMTP connectivity from the SeaTunnel worker host: nc -vz <smtp.host> <port> or swaks --to test@example.com.
- Check the wrapped cause ('Send email failed' has a cause chain) — look for AuthenticationFailedException (fix credentials) or unknown host (fix DNS).
- Confirm the attachment path (email.attachment_name) exists on the worker and the account allows outbound mail/attachments.
- Check firewall/egress rules so the worker can reach the SMTP server on the configured port (465/587/25).
Example fix
// before EmailSinkOptions.smtp_host = "localhost" // SMTP not running locally // after EmailSinkOptions.smtp_host = "smtp.gmail.com" EmailSinkOptions.smtp_port = 587 // with correct username/app-password credentials
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight SMTP connectivity and config check
Properties props = new Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.auth", "true");
Transport t = null;
try {
t = Session.getInstance(props).getTransport("smtp");
t.connect(smtpHost, user, password); // fails fast if host/auth/port wrong
} finally {
if (t != null && t.isConnected()) t.close();
} Try / catch
try {
emailSinkWriter.close();
} catch (EmailConnectorException e) {
if (EmailConnectorErrorCode.SEND_EMAIL_FAILED.equals(e.getSeaTunnelErrorCode())) {
Throwable cause = e.getCause();
log.error("SMTP send failed: " + (cause != null ? cause.getMessage() : "unknown"), e);
}
throw e;
} Prevention
- Validate smtp.host/port/auth settings against your mail provider docs before running jobs.
- Test SMTP reachability from worker hosts (firewall/egress) before production runs.
- Use app-specific passwords/OAuth where providers require them and rotate credentials.
- Ensure attachment paths exist and are readable on all worker nodes.
When it happens
Trigger: Closing an email sink after writing rows, when Transport.send fails: SMTP host unreachable, wrong port, TLS/SSL negotiation failure, authentication failure (wrong username/password), rejected recipients, or message content errors (bad attachments).
Common situations: Wrong smtp.host/port config; email provider requires OAuth/STARTTLS not configured; firewall or network egress blocked from the SeaTunnel worker; expired email account credentials; attachment file missing or unreadable.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- IotdbConnectorErrorCode.CLOSE_CLIENT_FAILED
- SNMP SET request timed out for agent {host}:{port}
- WRITE_FAILED
- Failed to fetch metadata from Gravitino for metadata: %s
- fail get tableSchema:
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/ab21d0e478604825.
Report an issue: GitHub.