Skip to main content
Lifecycle callbacks hook into each phase of an SMTP session. Set them as constructor options or override them on the server instance after construction. Call callback(null) to accept or callback(error) to reject. To send a custom SMTP error code, set error.responseCode:

onConnect

Called as soon as a client connects, before any SMTP dialogue. Use this to block connections by IP or apply rate limits.

Parameters

SMTPSession
required
The session object for this connection. See Session for details.
(err?: Error | null) => void
required
Call with null to accept the connection, or an Error to reject it.

Example

Rejecting in onConnect immediately closes the connection without sending a full SMTP greeting.

onSecure

Called after a successful TLS handshake (both implicit TLS and STARTTLS). Use this to inspect client certificates.

Parameters

Socket
required
The Bun socket object for this connection.
SMTPSession
required
The session object. After TLS is established, session.secure is true and session.tlsOptions contains cipher info.
(err?: Error | null) => void
required
Call with null to proceed, or an Error to close the connection.

Example


onAuth

Called when a client sends AUTH. The auth object varies by method — see the Authentication guide for details.

Parameters

AuthObject
required
Authentication credentials. Shape depends on the SASL method used.
SMTPSession
required
The session object.
(err: Error | null, response?: AuthResponse) => void
required
Call with (null, response) to accept, or (error) to reject.

AuthResponse

unknown
Stored on session.user for the rest of the connection. Use this to track the authenticated user.
string
Custom success message returned to the client.
number
Custom response code (default is 235).
Record<string, string>
XOAUTH2 error challenge data.

Examples


onMailFrom

Called when the client sends MAIL FROM. Use this to validate the sender address or enforce per-user sending policies.

Parameters

SMTPAddress
required
The sender address. See Session for the structure.Access ESMTP parameters via address.args:
SMTPSession
required
The session object. session.envelope.mailFrom will be set to this address if you accept.
(err?: Error | null) => void
required
Call with null to accept, or an Error to reject.

Example


onRcptTo

Called once per RCPT TO command. Reject unknown recipients here to avoid accepting mail you cannot deliver.

Parameters

SMTPAddress
required
The recipient address. Access DSN parameters via address.dsn:
SMTPSession
required
The session object. Accepted recipients are added to session.envelope.rcptTo.
(err?: Error | null) => void
required
Call with null to accept, or an Error to reject.

Example

onRcptTo is called separately for each recipient. A message can have multiple recipients if all are accepted.

onData

Called when the client begins sending the message body. stream is a ReadableStream<Uint8Array>. You must consume it completely before calling callback.

Parameters

DataStream
required
A ReadableStream<Uint8Array> containing the message data. Has two extra properties set after the stream closes:
SMTPSession
required
The session object. Access sender and recipients via session.envelope.
(err: Error | null, message?: string | Array<string | SMTPError>) => void
required
Call after fully consuming the stream.
  • First argument: null for success, Error to reject
  • Second argument (optional): Custom success message, or an array of per-recipient responses for LMTP

Examples

You must fully consume the stream before calling the callback. Failing to do so will cause the connection to hang.

onClose

Called when a connection closes, regardless of reason. No callback — return value is ignored. Use this for cleanup or logging.

Parameters

SMTPSession
required
The session object for the closed connection.

Example

onClose is always called, even if the connection was rejected during onConnect or terminated due to an error.