DMARC Report: Strategy Not Found when STARTTLS Fails

Issue Description

I have two queued DMARC reports recycling in queue, (one rua and one ruf) to the same provider.

They attempt to deliver, but fail to negotiate TLS, then Stalwart says it can’t find the strategy.

I don’t believe I have altered the appropriate connection strategy, but I can check configurations if you can’t replicate.

Expected Behavior

I’m not actually sure here. Should it fail to plaintext? It says end of file on TLS, so it attempts to negotiate and fails. Does Stalwart take this as a signal to retry with TLS later, assuming temporary issue, but this specific situation doesn’t have a fail condition in the strategy?

Relevant Log Output

2026-08-09T03:29:56Z INFO Delivery attempt started (delivery.attempt-start) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1
2026-08-09T03:29:56Z INFO New delivery attempt for domain (delivery.domain-delivery-start) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, domain = "shujii.com"
2026-08-09T03:29:56Z INFO MTA-STS policy not found (mta-sts.policy-not-found) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, domain = "shujii.com", strict = false, elapsed = 51ms
2026-08-09T03:29:56Z INFO TLSA record not DNSSEC signed (dane.tlsa-record-not-dnssec-signed) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, domain = "shujii.com", hostname = "mail.oliver.co.jp", strict = false, elapsed = 0ms
2026-08-09T03:29:56Z INFO Connecting to remote server (delivery.connect) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, domain = "shujii.com", hostname = "mail.oliver.co.jp", localIp = 10.0.1.100, remoteIp = 210.175.255.153, remotePort = 25, elapsed = 163ms
2026-08-09T03:29:57Z INFO STARTTLS error (delivery.start-tls-error) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, domain = "shujii.com", hostname = "mail.oliver.co.jp", reason = SMTP error occurred (smtp.error) { details = "I/O Error", reason = "tls handshake eof" }, elapsed = 305ms
2026-08-09T03:29:57Z WARN Strategy not found (smtp.id-not-found) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, id = "report", details = "Queue strategy not found"
2026-08-09T03:29:57Z INFO Message rescheduled for delivery (queue.rescheduled) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, nextRetry = 2026-08-09T05:29:57Z, nextDsn = 2083-03-15T14:55:08Z, expires = 2026-08-12T19:27:34Z
2026-08-09T03:29:57Z INFO Delivery attempt ended (delivery.attempt-end) queueId = 322648627820481536, queueName = "default", from = "[email protected]", to = ["[email protected]"], size = 3702, total = 1, elapsed = 1261ms

Stalwart Version

v0.16.x

Installation Method

Binary (Linux)

Database Backend

PostgreSQL

Blob Storage

S3-compatible

Search Engine

Internal

Directory Backend

Internal

Additional Context

v0.16.16

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

This is expected (if noisy) behavior, not a bug: the “Strategy not found” warning fires because Stalwart’s default routing expression assigns DMARC/TLS-RPT reports to a scheduling strategy named report, but out of the box there’s no MtaDeliverySchedule object actually named report defined. When lookup fails, Stalwart just falls back to its built‑in default schedule and logs a warning Queue strategy not found — it does not affect delivery or retry logic, and it is unrelated to the STARTTLS/TLS handshake failure that happened just before it in your log (that’s a separate, real delivery failure against mail.oliver.co.jp).

To make the warning go away, create a MtaDeliverySchedule named report in Settings › Mail Delivery, or change the schedule expression on your outbound strategy so it maps source == 'report' to an existing strategy name (e.g. default).

The actual delivery problem — tls handshake eof on STARTTLS to mail.oliver.co.jp:25 — is a remote server issue (it drops the connection during the TLS handshake) and Stalwart’s outbound TLS policy is optional by default, so it should retry per the (fallback) schedule; it is not stuck because of the missing strategy name.

Reference: MtaOutboundStrategy | Stalwart and Scheduling | Stalwart

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

Fixed in v0.16.18 (yet to be released).

Just noticed another one of these go by in the log, and I am running v0.16.18

2026-08-21T21:13:45Z INFO DMARC aggregate is being prepared (outgoing-report.dmarc-aggregate-report) reportId = 1787260425, domain = "ontuscia.it", rangeFrom = 2026-08-20T21:13:45Z, rangeTo = 2026-08-21T21:13:45Z
2026-08-21T21:13:45Z WARN Strategy not found (smtp.id-not-found) id = "report", details = "Queue strategy not found"

The 0.16.18 change is why it moved: source-based expressions now match at enqueue rather than on the delivery attempt, so the same underlying condition surfaces when the report is prepared instead of when it is sent. The warning itself is unrelated to the STARTTLS failure and is telling you something real.

It means no delivery schedule named report is loaded. Check Settings > MTA > Outbound > Delivery Schedules. There are two ways to end up here: the object genuinely does not exist (the defaults are only seeded on a first run where no virtual queues and no delivery schedules exist at all), or it exists but its virtual queue reference is dangling, in which case it gets discarded at config load and you should see a corresponding build error under your configuration errors.

Your own first log corroborates it: the report went out on queueName = "default", which is the built-in fallback rather than the report queue. Delivery is not failing because of this, but it is worth fixing rather than living with, as the strategy docs say.

I think I understand, so the original fix in 0.16.18 changed the behavior to stop using ‘default’ and now start using ‘report’, but it didn’t fix the fact that ‘report’ strategy still doesn’t exist - I still need to add that manually.

Would a fresh installation still have this issue, or is there a ‘report’ strategy out of the box now?