Logging consistency: queue ID

Issue Description

When receiving a message from an external Internet host, Stalwart reports a base-16 (hex) queue ID to the connecting mail server, while logging a base-10 queue ID to the log files.

Suggest amending the local log queue ID format to be base-16/HEX to facilitate locating a local issue with a remote queue ID.

Expected Behavior

Local logging of Queue ID would be better in base-16

Actual Behavior

Local log of queue ID is base-10

Reproduction Steps

Send an email externally, note the queue ID stalwart replies with, and check against Stalwart logs.

Relevant Log Output

Log output for reference:
— Postfix (Sending server) Log —
2026-05-19T15:53:03.803679-04:00 mail postfix/smtp[110698]: E39C9A3A7B: to=[email protected], relay=stalwart.server.tld[]:25, delay=0.89, delays=0.21/0/0.02/0.65, dsn=2.0.0, s
tatus=sent (250 2.0.0 Message queued with id 446ca8a04e07a00.)
2026-05-19T15:53:03.804311-04:00 mail postfix/qmgr[1596432]: E39C9A3A7B: removed

— Stalwart (Receiving server) Log —
2026-05-19T19:53:03Z INFO SMTP EHLO command (smtp.ehlo) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, domain = “”
2026-05-19T19:53:03Z INFO SPF EHLO check failed (smtp.spf-ehlo-fail) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, domain = “”, result =
SPF check failed (spf.fail), elapsed = 0ms
2026-05-19T19:53:03Z INFO TLS handshake (tls.handshake) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, listenerId = “smtp”, version = “TLSv1_3”, details =
“TLS13_AES_256_GCM_SHA384”
2026-05-19T19:53:03Z INFO IPREV check passed (smtp.iprev-pass) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, domain = “”, result = IPREV
check passed (iprev.pass) { details = [“_gateway.”] }, elapsed = 5ms
2026-05-19T19:53:03Z INFO SPF From check failed (smtp.spf-from-fail) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, domain = “”, from = "
[email protected]", result = SPF check failed (spf.fail), elapsed = 0ms
2026-05-19T19:53:03Z INFO SMTP MAIL FROM command (smtp.mail-from) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, from = “[email protected]
2026-05-19T19:53:03Z INFO SMTP RCPT TO command (smtp.rcpt-to) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, to = “[email protected]
2026-05-19T19:53:03Z INFO DKIM verification passed (smtp.dkim-pass) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, strict = false, result = [DKIM verificat
ion passed (dkim.pass) { domain = “testdomain.tld” }], elapsed = 0ms
2026-05-19T19:53:03Z INFO DMARC check passed (smtp.dmarc-pass) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, strict = false, domain = “testdomain.tld”, pol
icy = “quarantine”, result = DMARC check passed (dmarc.pass), elapsed = 0ms
2026-05-19T19:53:03Z INFO DMARC report rate limited (outgoing-report.dmarc-rate-limited) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, limit = [1, 8640000
0ms]
2026-05-19T19:53:03Z INFO Milter action: Accept (milter.action-accept) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, id = “MtaMilter with id iqrloazqaaqa”
, elapsed = 388ms
2026-05-19T19:53:03Z INFO Queued message for delivery (queue.message-queued) listenerId = “smtp”, localPort = 25, remoteIp = , remotePort = 48584, queueId = 308156318657575424, f
rom = “[email protected]”, to = [“[email protected]”], size = 21454, nextRetry = 2026-05-19T19:53:03Z, nextDsn = 2026-05-20T19:53:03Z, expires = 2026-05-22T19:53:03Z
2026-05-19T19:53:03Z INFO Delivery attempt started (delivery.attempt-start) queueId = 308156318657575424, queueName = “local”, from = “[email protected]”, to = [“[email protected]”],
size = 21454, total = 1
2026-05-19T19:53:03Z INFO New delivery attempt for domain (delivery.domain-delivery-start) queueId = 308156318657575424, queueName = “local”, from = “[email protected]”, to = [“rmerigo
[email protected]”], size = 21454, total = 1, domain = “igcom.ca”
2026-05-19T19:53:03Z INFO Message ingested (message-ingest.ham) queueId = 308156318657575424, queueName = “local”, from = “[email protected]”, to = [“[email protected]”], size = 21454
, total = 1, accountId = 25, documentId = 59, mailboxId = [0], blobId = “48ac9a7edb75c676e48420dff1b138480782f3031036435910366ed53948d210”, changeId = 136, messageId = “5c400b66-3236-4577-9d
[email protected]”, size = 21454, elapsed = 1ms
2026-05-19T19:53:03Z INFO DSN success notification (delivery.dsn-success) queueId = 308156318657575424, queueName = “local”, from = “[email protected]”, to = [“[email protected]”], si
ze = 21454, total = 1, to = “[email protected]”, hostname = “localhost”, code = 250, details = “OK”
2026-05-19T19:53:03Z INFO Delivery completed (delivery.completed) queueId = 308156318657575424, queueName = “local”, from = “[email protected]”, to = [“[email protected]”], size = 214
54, total = 1, elapsed = 0ms
2026-05-19T19:53:03Z INFO Delivery attempt ended (delivery.attempt-end) queueId = 308156318657575424, queueName = “local”, from = “[email protected]”, to = [“[email protected]”], size
= 21454, total = 1, elapsed = 1ms

Stalwart Version

v0.16.x

Installation Method

Built from source

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

LDAP

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

Let me look into how Stalwart formats the queue ID in SMTP responses versus logging.

This is a confirmed behavioral inconsistency in the Stalwart source code. Looking directly at the relevant source file (crates/smtp/src/inbound/data.rs, line 733):

format!("250 2.0.0 Message queued with id {queue_id:x}.\r\n")

The {queue_id:x} format specifier outputs the queue ID in hexadecimal (lowercase) in the SMTP 250 response sent to the remote server. However, the queueId field logged via the tracing subsystem (trc) is emitted as a plain u64 integer (decimal). So the same underlying number is presented as hex externally and decimal internally.

Your observation is correct:

  • SMTP response to sender: 446ca8a04e07a00 (hex)
  • Stalwart logs: 308156318657575424 (decimal - the same number: 0x446ca8a04e07a00 = 308156318657575424)

This is a straightforward consistency bug - the log emission of Key::QueueId should format the value as hex to match what is advertised to sending servers. Since this is a source-level issue, it would require a code change in the server. A human maintainer will need to follow up on this.

As a workaround in the meantime, you can convert between the two yourself:

  • Hex to decimal: printf '%d\n' 0x446ca8a04e07a00
  • Decimal to hex: printf '%x\n' 308156318657575424

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong. If you found it useful, mention @helpbot in any reply to ask follow-up questions and the bot will respond again.