runtime behaviour

Details

Options are validated before a run starts. Almost all of them combine freely; this page covers the handful that do not, and the one group that quietly does nothing when you are writing to disk instead of sending.

Each section says what happens if you get it wrong. If you want working commands rather than rules, recipes has them, and features lists every option with its default.

Accurate as of SMTPBench 1.2.1

Options that need a partner

The run stops before anything is sent

Some settings only mean something alongside another. Supplying one without the other is treated as a mistake rather than quietly ignored, so you find out immediately instead of wondering why nothing changed.

If you use…You must also provide…Why
recipient_filelb_host= or eml_out_dir=A multi-domain recipient list has no single MX target. Everything goes through one relay, or to disk.
journal_filejournal=trueSupplying journal addresses without enabling journaling would do nothing.
journal=true with recipient_filejournal_address= or journal_file=Journaling normally falls back to the single recipient, and there is not one. Fails fast rather than journaling nowhere.
recipient_file_orderrecipient_fileOrdering a list you never supplied is a mistake, not a no-op.
from_file_orderfrom_fileSame.
journal_file_orderjournal_fileSame.
usernamepasswordBoth halves or neither.
passwordusernameBoth halves or neither.
SMTPBENCH_USERSMTPBENCH_PASSThe same rule applies to the environment variables.

One value is range-checked as well: attachment_probability must be between 0 and 1.

Options that cannot be combined

The run stops before anything is sent

A few settings answer the same question in different ways, so asking for both has no coherent meaning. SMTPBench rejects the run rather than picking one and hoping it guessed right.

Attachment modes

Three ways to attach a file. Pick one: attachment_path is "this exact file every time," attachment_size is "generate bytes," attachment_dir is "sample real files." They answer the same question three different ways, so combining them has no coherent meaning.

attachment_pathattachment_sizeattachment_dir
attachment_pathsame optionconflict, errors before sendingconflict, errors before sending
attachment_sizeconflict, errors before sendingsame optionconflict, errors before sending
attachment_dirconflict, errors before sendingconflict, errors before sendingsame option

Attachment modes vs. modifiers

Two conflicts, each for a reason. attachment_path means "attach this one file to every message," so asking for a variable count or a probability contradicts it. Use attachment_size or attachment_dir if you want variation. And corpus files keep their own names, so renaming every sampled file to one fixed name would defeat the point of sampling a corpus.

attachment_countattachment_probabilityattachment_filenameattachment_mime_type
attachment_pathconflict, errors before sendingconflict, errors before sendingworks togetherworks together
attachment_sizeworks togetherworks togetherworks togetherworks together
attachment_dirworks togetherworks togetherconflict, errors before sendingworks together

Pacing

rate is the sole pacing mechanism when present. It is a whole-run token bucket, and a per-thread delay on top of it would make the resulting throughput meaningless.

ratedelayrandom_delay
ratesame optionconflict, errors before sendingconflict, errors before sending
delayconflict, errors before sendingsame optionaccepted, behaviour undocumented
random_delayconflict, errors before sendingaccepted, behaviour undocumentedsame option

delay together with random_delay is accepted without error, but which one governs is not documented. Do not build anything on that combination.

Address lists and single addresses

A file option and its single-value sibling cannot both be set. Mixing across fields is fine: recipient_file= with a single from_address= is a perfectly normal run.

File optionConflicts with
recipient_filerecipient
from_filefrom_address
journal_filejournal_address

When one option wins

A warning prints, the run continues

One case, and the only rule on this page that lets the run continue.

CombinationResult
tls_mode + use_tlstls_mode wins.

Options ignored offline

No error, no warning, no effect

With eml_out_dir= set, SMTPBench composes messages and writes them to disk. It never opens a connection: no DNS, no MX lookup, no banner check, no SMTP transaction. Anything about connecting is therefore inert. These are accepted without complaint and do nothing:

OptionWhy it does nothing offline
max_retriesThe offline write path returns before the retry loop is ever reached.
retry_delaySame reason: the retry loop never runs.
tls_mode / use_tlsNo connection to secure.
lb_hostNo connection to make.
transaction_timeoutNo transaction to time out.

What still works: every attachment_* option, body_text_dir, from_address and from_file, recipient_file, journal, threads, messages, rate, delay, and all logging. Composition happens before the offline branch, so anything that shapes a message behaves identically. Since 1.2.1, port= is not required offline either: pass it and the summary records it, omit it and the summary records null.