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_file | lb_host= or eml_out_dir= | A multi-domain recipient list has no single MX target. Everything goes through one relay, or to disk. |
| journal_file | journal=true | Supplying journal addresses without enabling journaling would do nothing. |
| journal=true with recipient_file | journal_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_order | recipient_file | Ordering a list you never supplied is a mistake, not a no-op. |
| from_file_order | from_file | Same. |
| journal_file_order | journal_file | Same. |
| username | password | Both halves or neither. |
| password | username | Both halves or neither. |
| SMTPBENCH_USER | SMTPBENCH_PASS | The 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_path | attachment_size | attachment_dir | |
|---|---|---|---|
| attachment_path | same option | conflict, errors before sending | conflict, errors before sending |
| attachment_size | conflict, errors before sending | same option | conflict, errors before sending |
| attachment_dir | conflict, errors before sending | conflict, errors before sending | same 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_count | attachment_probability | attachment_filename | attachment_mime_type | |
|---|---|---|---|---|
| attachment_path | conflict, errors before sending | conflict, errors before sending | works together | works together |
| attachment_size | works together | works together | works together | works together |
| attachment_dir | works together | works together | conflict, errors before sending | works 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.
| rate | delay | random_delay | |
|---|---|---|---|
| rate | same option | conflict, errors before sending | conflict, errors before sending |
| delay | conflict, errors before sending | same option | accepted, behaviour undocumented |
| random_delay | conflict, errors before sending | accepted, behaviour undocumented | same 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 option | Conflicts with |
|---|---|
| recipient_file | recipient |
| from_file | from_address |
| journal_file | journal_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.
| Combination | Result |
|---|---|
| tls_mode + use_tls | tls_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:
| Option | Why it does nothing offline |
|---|---|
| max_retries | The offline write path returns before the retry loop is ever reached. |
| retry_delay | Same reason: the retry loop never runs. |
| tls_mode / use_tls | No connection to secure. |
| lb_host | No connection to make. |
| transaction_timeout | No 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.