Complete vSMTP TOML key/value list

The behavior of your server can be configured using a configuration file, and using the -c, --config flag of the vsmtp.

All the parameters are optional and have default values. If -c, --config is not provided, the default values of the configuration will be used.

The configuration file will be read and parsed right after starting the program, producing an error if there is an invalid syntax, a filepath failed to be opened, or any kind of errors.

If you have a non-explicit error when you start your server, you can create an issue on the github repo, or ask for help in our discord server.


The configuration file format is TOML.


You will find examples here and the technical documentation here.



The only mandatory parameter to provide. This parameter is follow the semver format. It is used to specify the version require of vsmtp to parse successfully this file.


version_requirement = ">=1.0.0, <2.0.0"



domain = ""


client_count_max = 16


user = "vsmtp"
group = "vsmtp"
group_local = "vsmtp"


receiver = 6
processing = 6
delivery = 6


vSMTP can be used as a MTA and/or a MSA.

A MTA listen on port 25, and using server side authentication (SPF / DKIM / DMARC …) to be protected from spam and identity substitution.

A MSA listen on port 587 and 465 (with TLS tunnel), in the same fashion than HTTP over port 80 and HTTPS over 443. On these ports, stronger policies apply and client side authentication (SASL) is required.

Expose your public addresses here, (support both ipv4 and ipv6) :

addr = [""]                  # <---- MTA's addresses
addr_submission = [""]      # <---- MSA's addresses
addr_submissions = [""]     # <---- MSA's addresses for SMTPS

These field are arrays, and you can leave any of them empty. Make sure to provide at least one address, otherwise an error will be produced on startup.

You might want to add local address ( for example) when using delegation services.


filepath = "/var/log/vsmtp/vsmtp.log"
level = [


dirpath = "/var/spool/vsmtp"


channel_size = 32

channel_size = 32
deferred_retry_max = 100
deferred_retry_period = "5m"


security_level = "Encrypt"
preempt_cipherlist = false
handshake_timeout = "200ms"
protocol_version = "TLSv1.3"
certificate = "/etc/vsmtp/tls/"
private_key = "/etc/vsmtp/tls/"



type = "system"

protocol_version = "TLSv1.3"
certificate = "/etc/vsmtp/tls/"
private_key = "/etc/vsmtp/tls/"

protocol_version = "TLSv1.3"
certificate = "/etc/vsmtp/tls/"
private_key = "/etc/vsmtp/tls/"

type = "google"


rcpt_count_max = 1000
disable_ehlo = false
required_extension = ["STARTTLS", "SMTPUTF8", "8BITMIME", "AUTH"]


soft_count = 10
hard_count = 20
delay = "5s"


connect = "5m"
helo = "5m"
mail_from = "5m"
rcpt_to = "5m"
data = "5m"


must_be_authenticated = true
enable_dangerous_mechanism_in_clair = true
mechanism = ["PLAIN", "LOGIN", "CRAM-MD5", "ANONYMOUS"]


type = "custom"

domain = ""
search = [""]
name_servers = []

# Sets the number of dots that must appear (unless it's a final dot representing the root)
#  that must appear before a query is assumed to include the TLD. The default is one, which
#  means that `www` would never be assumed to be a TLD, and would always be appended to either
#  the search
ndots = 1
# Number of retries after lookup failure before giving up. Defaults to 2
attempts = 2
# Rotate through the resource records in the response (if there is more than one for a given name)
rotate = false
# Enable edns, for larger records
edns0 = false
# Use DNSSec to validate the request
validate = false
# The ip_strategy for the Resolver to use when lookup Ipv4 or Ipv6 addresses
ip_strategy = "Ipv4thenIpv6"
# Cache size is in number of records (some records can be large)
cache_size = 32
# Check /ect/hosts file before dns requery (only works for unix like OS)
use_hosts_file = true
# Number of concurrent requests per query
# Where more than one nameserver is configured, this configures the resolver to send queries
# to a number of servers in parallel. Defaults to 2; 0 or 1 will execute requests serially.
num_concurrent_reqs = 2
# Preserve all intermediate records in the lookup response, suchas CNAME records
preserve_intermediates = true
# Try queries over TCP if they fail over UDP.
try_tcp_on_error = false


dirpath = "/var/spool/vsmtp/app"


filepath = "/etc/vsmtp/main.vsl"


filepath = "/var/log/vsmtp/app.log"
level = "WARN"
format = "{d} - {m}{n}"
size_limit = 10485760
archive_count = 10