❌

Normale weergave

v0.16.27

18 Oktober 2026 om 21:28

[0.16.27] - 2026-10-18

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • IMAP:
    • APPEND and COPY/MOVE into another account's mailbox do not change the JMAP EmailDelivery state.
    • SEARCH RETURN with MIN or MAX alongside ALL returns only the minimum and maximum in ALL, and SAVE combined with MIN or MAX and ALL or COUNT saves only the minimum and maximum instead of every match.
  • iTIP: Merging a received update does not copy the VTIMEZONE definitions it carries, so an occurrence moved by an external organizer can reference a TZID (for example W. Europe Standard Time) the stored event no longer defines, and Apple Calendar shows both the original and the moved occurrence.
  • OAuth: Loopback redirect URIs without a path (for example http://127.0.0.1:45678) are not matched against registered loopback URIs on any port and are rejected by dynamic client registration.
  • WebDAV: PROPFIND allprop returns DAV:current-user-principal, so Windows Explorer shows every file and folder under the account name.

Check binary attestation here

  •  

v0.16.26

11 Oktober 2026 om 19:33

[0.16.26] - 2026-10-11

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • sd_notify support.
  • JMAP: Mailbox/set allows moving a mailbox under a parent that already has a child with the same name, and rejects renames that only change the case of a mailbox name with alreadyExists.

Changed

Fixed

  • DNSSEC: Use hickory-resolver patched fork at https://github.com/stalwartlabs/hickory-dns.
  • RocksDB: Blob garbage collection rewrites every stored blob on each compaction of the blobs column family, about once per 128MB of new mail.
  • Milter: End-of-headers is not sent to milters that negotiate SMFIP_NOHDRS without SMFIP_NOEOH, so the transaction stalls until it times out.
  • OIDC: When the access token lacks the claimUsername claim but has an email claim, the account is built from email without consulting the userinfo endpoint.
  • JMAP:
    • onSuccessUpdateEmail and onSuccessDestroyEmail entries in EmailSubmission/set that name an existing submission by id update or destroy the Email with the same id instead of the submission's own Email.
    • A VacationResponse/set that only sets isEnabled on an account without a vacation response activates an empty Sieve script.

Check binary attestation here

  •  

v0.16.25

5 Oktober 2026 om 08:57

[0.16.25] - 2026-10-05

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • JMAP: Creating a MaskedEmail with emailDomain fails with forbidden for every domain when the account has addresses on more than one domain.
  • Autodiscover: Requests for a response schema other than Outlook's, such as ActiveSync (mobilesync), are answered with the Outlook settings instead of error 601.
  • IMAP:
    • LOGIN and AUTHENTICATE with a wrong, expired or unknown app password or API key are answered with an untagged NO, so clients keep waiting for the command to complete until the connection times out.
    • The failed login that exceeds the maximum number of authentication failures is answered with an untagged NO before the connection is closed.
  • DKIM:
    • A rotation moves the active key to retiring even when its successor fails to publish or propagate, so outgoing mail is sent unsigned until a retry publishes the new key. The DNS write failure is also not logged and the task reports success.
    • Keys created while DNS management was manual, or before DKIM was added to the published records, are never rotated after DNS management becomes automatic. Domains already affected start rotating once a DkimManagement task is created for them.
    • After switching DNS management from automatic to manual, a due rotation activates a new key that was never published in DNS, so signatures fail verification, and retiring the old key is retried forever.
  • Spam filter:
    • Messages with no text line long enough for a Pyzor digest are checked with the digest of empty input and tagged PYZOR.
    • DNSBL answers with several return codes, such as a Spamhaus ZEN listing in both SBL and PBL, are scored for only the first code returned.
    • DNSBL lookups that return "not listed" are cached for 24 hours regardless of the zone's negative TTL.
    • Removing a duplicate training sample of a message reclassified on the same day clears the blob link of the sample that is kept.
  • MTA: Queue quotas with an empty match expression are never enforced, including the global queue quota created on first start.
  • RocksDB: The info log (LOG, LOG.old.*) grows without limit because log rotation and retention are left at RocksDB defaults.
  • WebUI: A blob store read error at startup, such as an S3 authentication failure, stops the web interface from being downloaded.

Check binary attestation here

  •  

v0.16.24

27 September 2026 om 20:28

[0.16.24] - 2026-09-27

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • DNS: PowerDNS Authoritative provider for automatic DNS record management.

Changed

Fixed

  • Troubleshoot tool: TLSA records are looked up for every MX host, including hosts whose zone is not DNSSEC signed.
  • Spam filter:
    • OpenPhish and PhishTank entries containing uppercase characters never match, since message URLs are lowercased while HTTP lookup entries keep their original case. HTTP lookups now match keys case-insensitively.
    • URL shortener links are followed using the lowercased URL, so case-sensitive short links resolve to the wrong destination or not at all.
    • Incremental training never advances its position past the first run, so every retained sample added since then is trained again, and counted again in the reservoir, on each run until it expires.
    • Updating the rules only adds new objects, so upstream changes to existing rules, DNSBL servers, HTTP lookups, lookup keys and file extensions never reach an existing installation.
    • Updating the rules reports success when objects fail to import, or when a configuration error stops the updated settings from being activated.
  • JMAP:
    • A PushSubscription created within the verification rate limit window of another one on the same account never receives its PushVerification, since the blocked verification is dropped instead of being sent once the window expires.
    • A push notification retried after a failed delivery can report an older state than a change queued during the failed attempt, since the older state changes are merged last and overwrite the newer ones.
    • Changes made while a push request is in flight are not delivered until the next change reaches the same subscription, since a successful delivery cancels the pending retry.
    • The VAPID aud claim is derived from a hand-written parse of the push URL, so a crafted push URL can make the server sign a token for a push service other than the one the request is sent to.
    • Email/import rejects a blobId that refers to a Blob/upload creation id in the same request ("#u0") with Invalid blob id..
    • Email/set with a full mailboxIds object identical to the current mailboxes, together with a keyword change, stores the message with IMAP UID 0, so IMAP clients stop seeing it.
  • MTA:
    • A node without the outboundMta role stops replying to DATA and to JMAP submissions once about 1024 messages have been queued on it.
    • MX records are resolved through the DNSSEC-validating resolver even when DANE is disabled.
    • A DATA stage Sieve script does not see headers added by milters or MTA hooks, and discards every milter and MTA hook change when it edits the message.
  • MySQL: Range deletions and search index removals start with a single unbounded DELETE and switch to chunks only after a timeout.
  • IMAP: COPY and MOVE fail with NO [CONTACTADMIN] when another session changes the same message at the same time.
  • Autodiscover: Implicit TLS ports (993, 995, 465) are advertised with <Encryption>TLS</Encryption>, which Outlook reads as STARTTLS.
  • HTTP: Idle keep-alive connections are never closed.

Check binary attestation here

  •  

v0.16.23

21 September 2026 om 11:57

[0.16.23] - 2026-09-21

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • Expressions: bit_and function.

Changed

Fixed

  • MTA:
    • A mailing list whose recipients include another mailing list is accepted at RCPT TO and then rejected at local delivery with 550 5.5.0 Mailbox not found.
    • DMARC aggregate reports carry two spf elements per record and the version element of a DMARC aggregate report is written as 1 instead of 1.0.
    • DSNs generated for an alias rewrite or a list expansion emit a doubled addr-type in Original-Recipient (rfc822;rfc822;user@example.org).
    • DSNs that cannot be written to the store are discarded, the recipients are flagged as notified and the original message is removed from the queue, losing both the bounce and the message.
  • POP3:
    • TOP msg n counts the n lines from the first byte of the message instead of from the first byte of the body.
    • A message whose very first line begins with . is not byte-stuffed.
  • Spam filter: Moving or copying a message from one account into another creates no training sample, so the classifier never learns from it.
  • Sieve: envelope "orcpt" yields the bare address for an ORCPT supplied over SMTP. It now carries the addr-type prefix in every case, as required by RFC 6009.
  • ACME: The _acme-challenge TXT records published for a DNS-01 authorization are never removed.
  • DNS: The DNSSEC resolver queries a single nameserver at a time, working around a hickory-resolver race that cancels the TCP retry when two nameservers return a truncated response in parallel.
  • Troubleshoot tool:
    • MX records are resolved through the DNSSEC-validating resolver, matching the resolver used by the delivery path.
    • A TLSA lookup that fails or returns bogus records stops the delivery attempt for that host, instead of continuing without DANE.
  • OIDC: Bearer tokens that carry no email, preferred_username or upn claim are always authenticated against the default directory.
  • Meilisearch: A confirmation timeout is treated as a failed write even when failOnTimeout is disabled, so an index whose batches take longer than pollInterval x maxRetries never completes an indexing task and resubmits the same batch indefinitely.
  • WebUI: A failed update no longer takes an Application offline.
  • FoundationDB: The cached read version is invalidated when any broadcast is received from another node.
  • Redis:
    • On a cluster, the rate limiter and the blob upload quota issue INCR and EXPIRE as a MULTI/EXEC transaction, whose MOVED redirects collapse into a single EXECABORT that never refreshes the slot map.
    • A connection that fails because it is addressing the wrong server is returned to the pool and reused, since the recycle check only issues PING.

Check binary attestation here

  •  

v0.16.22

13 September 2026 om 20:43

[0.16.22] - 2026-09-13

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • WebDAV: PROPFIND responses do not declare the namespace of every requested property on the DAV:multistatus element.
  • MTA:
    • SMTP session state obtained before STARTTLS is discarded once the TLS handshake completes, as required by RFC 3207.
    • Inbound throttle, outbound throttle and queue quota match expressions evaluate their if/then conditions.
    • DMARC: Messages without an aligned SPF or DKIM pass from a domain that publishes a DMARC policy are reported as fail instead of none in logs.
    • DMARC: A temporary DNS error on an SPF or DKIM check whose identifier aligns with the author domain produces temperror instead of fail.
    • DMARC: A policy record without a p tag is only applied, as p=none, when it contains a rua tag, even if it declares sp or np.
  • iMIP: Notification subjects and bodies omit the event start date, time and timezone for recurring events.
  • OIDC: Discovery is retried for 30 seconds before the directory is marked as unavailable, so a provider that is still starting up no longer requires a restart.
  • WebUI: The cached bundle of an Application is discarded when its resourceUrl changes or the record is deleted, so the next unpack fetches the new resource.
  • DNS: Append . to MX record hostnames.
  • Recovery mode: Automatic IP banning is disabled during recovery and initial setup.
  • FoundationDB: The cached read version is invalidated when a queue refresh or registry change broadcast is received.
  • Sieve: Messages filed with fileinto by a user script are treated as ham and are no longer moved to Junk when classified as spam.
  • IMAP:
    • SELECT, EXAMINE and STATUS on a shared mailbox require the r (read) right.
    • AUTHENTICATE is refused on clear-text connections unless allowPlainTextAuth is enabled, and the greeting and CAPABILITY response advertise LOGINDISABLED instead of the AUTH= mechanisms in that case.
  • IMAP, POP3, ManageSieve: Partial commands received before STARTTLS or STLS are discarded once the TLS handshake completes.
  • Network: Inbound TLS handshakes, both implicit and STARTTLS, are aborted after the listener's tlsTimeout, releasing the connection slot.
  • OAuth: A random key is used when the OIDC provider's encryptionKey or HMAC signatureKey cannot be read, instead of an empty key.
  • LDAP: The {local} and {domain} filter placeholders are escaped.
  • JMAP:
    • CalendarEvent/set stores useDefaultAlerts per user, and CalendarEvent/get returns false when it was never set.
    • CalendarEvent/get returns null for baseEventId unless the id is a synthetic recurrence instance.
    • CalendarEvent/get returns null for requested recurrenceRule and recurrenceOverrides properties on synthetic recurrence instances.
    • CalendarEvent/get and ContactCard/get return only id when the properties argument is an empty list, instead of every property.

Check binary attestation here

  •  

v0.16.21

6 September 2026 om 18:48

[0.16.21] - 2026-09-06

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

  • Sieve: Messages generated by user scripts are DKIM signed through the new SieveUserInterpreter.dkimSignDomain setting, which defaults to the account's own domain.

Fixed

  • JMAP:
    • CalendarEvent/set requests that ask for scheduling messages are rejected with a forbidden error when the account cannot send them.
    • Calendar/get and AddressBook/get return every property when the properties argument is omitted or null.
    • EventSource ping events advertise the interval in seconds rather than milliseconds.
    • Calendar synthetic ids returned when expanding recurrences identify an occurrence by its recurrence id.
  • IMAP: Every command in a pipelined STATUS or FETCH batch receives its tagged completion, instead of the first failing command dropping the responses for all commands queued behind it.
  • WebDAV: Accounts without a storage quota no longer advertise a 4 GiB limit in DAV:quota-available-bytes.
  • MTA: Inbound DMARC and TLS aggregate reports that a reporter sends more than once are imported again as a duplicate entry.
  • Spam filter: Domain and URL blocklists are queried only for text written as a link.
  • iTIP: Detaching an occurrence that the recurrence rule already generates is sent as a METHOD:REQUEST carrying the RECURRENCE-ID instead of a METHOD:ADD.
  • Sieve: fileinto :specialuse and specialuse_exists accept special-use attributes in the \Trash form.
  • LDAP: Active Directory servers that answer an unauthenticated bind (a non-empty DN with a zero-length password) with success no longer authenticate accounts without a password.
  • Network: Listeners bound to the unspecified IPv6 address ([::]) fall back to IPv4 when socket creation fails with EPROTONOSUPPORT.
  • OpenTelemetry: log exporter does not include the parent span's attributes.

Check binary attestation here

  •  

v0.16.20

30 Augustus 2026 om 15:43

[0.16.20] - 2026-08-30

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • System for Cross-domain Identity Management (SCIM) v2 (Enterprise):
  • JMAP: CalendarEvent/set support for updating and deleting synthetic ids (#2925).
  • Calendar:
    • Conference links in calendar invites and email alarms.
    • Translations for Arabic, Brazilian Portuguese, Bulgarian, Chinese Simplified, Chinese Traditional, Croatian, Czech, Finnish, Hebrew, Hindi, Hungarian, Indonesian, Japanese, Korean, Lithuanian, Norwegian BokmΓ₯l, Persian, Romanian, Russian, Slovak, Slovenian, Thai, Turkish, Ukrainian and Vietnamese.

Changed

  • Calendar: Updated HTTP RSVP page.

Fixed

  • DANE:
    • TLSA records are looked up whenever the MX RRset is signed, even when the MX host's own zone is not.
    • Mandatory DANE failures are permanent rather than temporary, bouncing messages that should be delayed.
    • Valid but unusable TLSA records fall back to the configured TLS strategy, permitting cleartext delivery where TLS is required.
  • S3: Fix outdated upstream af-south-1 region configuration.
  • Setup wizard: SQL directories set to use the main data store are now validated against the data store being configured.
  • CardDAV: Delete default address book id when deleting the default address book.
  • Redis: Sentinel deployments configured with rediss:// URLs now connect to the master over TLS instead of silently falling back to cleartext.
  • Email: Generated Message-ID headers use the hostname of the node that built the message instead of the configured server hostname.
  • MTA:
    • Do not send DMARC reports to local domains.
    • Messages addressed to an inboundReportAddresses match are only discarded when they actually contain a report (#1088).
  • Directory: Impersonation using the recovery admin fails when the impersonated account has not logged in before (LDAP and SQL directories).
  • WebUI: Failed logins open the browser's native credential prompt.
  • Cluster: Expired node id leases are released periodically rather than only during startup, so entries for removed nodes no longer remain Stale or Inactive indefinitely.

Check binary attestation here

  •  

v0.16.19

24 Augustus 2026 om 22:04

[0.16.19] - 2026-08-24

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • WebUI: oauthClientId setting in Application, which allows the WebUI to use a different OAuth client than the default.
  • Sieve: env.spam.score and env.spam.is_spam variables, which expose the spam filter result to system scripts running at the DATA stage.
  • CalDAV: vCardVersion setting in AddressBook, which allows the default vCard version to be specified when the client does not request a specific version.

Changed

  • MySQL & MariaDB: Key columns are now VARBINARY(255) with a full-length primary key instead of TINYBLOB. Note: Existing deployments should run, once per table, for each of the tables a, d, e, f, g, h, j, k, l, m, n, o, p, q, r, s, t, u, w, x and y the command ALTER TABLE a MODIFY k VARBINARY(255) NOT NULL;.

Fixed

  • ACME:
    • Order and authorization failures are never logged, so an order rejected by the CA.
    • An order rejected by the CA marks the renewal task as permanently failed.
  • CalDAV:
    • Attendee addresses whose mailto: URI percent-encodes a full name-addr are silently dropped from the scheduling snapshot.
    • Attendees whose calendar user address cannot be parsed should be flagged with SCHEDULE-STATUS=3.7.
    • The RSVP link in an iMIP invitation stamps PARTSTAT on the organizer's copy of the event only, leaving a local attendee's own copy at NEEDS-ACTION and sending the organizer no reply.
    • MKCALENDAR, MKCOL and PROPPATCH store the display name, description, time zone and the other per-user properties under the authenticated account rather than the account that owns the collection.
  • Directory:
    • An empty column, attribute or claim returned by an external directory is synchronized as an empty string rather than a missing value.
    • /api/discover splits the account name on @ without accounting for the % master user separator or the recovery administrator.
  • FoundationDB: Older chunked entries are not deleted.
  • IMAP: SETACL and DELETEACL fail to resolve an identifier spelled with uppercase characters.
  • iMIP: Invitations, replies and cancellations reference a TZID parameter with no matching VTIMEZONE component whenever the event was stored without one.
  • JMAP:
    • AddressBook/get: A new account's default address book is never recorded.
    • Email/get and Email/parse with fetchAllBodyValues return body values only for the parts listed in textBody or htmlBody, omitting every other text/* part in bodyStructure.
    • Email/set writes display names as an RFC 2047 encoded-word wrapped in a quoted-string, which RFC 2047 forbids.
    • Mailbox/set, AddressBook/set and Calendar/set store isSubscribed and the other per-user properties under the authenticated account rather than the account named in the request.
    • Principal/query returns no results when the name or email filter is spelled with uppercase characters.
    • FileNode/set: File nodes created over JMAP are returned with a <D:href> holding the raw name over WebDAV.
  • Meilisearch:
    • Queries return at most 1000 results, as the maxTotalHits pagination setting is left at the Meilisearch default.
    • Searches combining several terms return documents that match only some of them.
    • A task confirmation timeout is reported as a success when failOnTimeout is disabled.
  • Import: --import always aborts with the target database already containing data in the key range being imported.
  • MTA:
    • A domain catchAllAddress pointing to a mailing list or a sub-addressed mailbox is accepted at RCPT TO and then rejected at local delivery with 550 5.5.0 Mailbox not found.
    • is_local_address() and is_local_domain() expression functions do not match an address or domain spelled with uppercase characters.
    • Relay routes are rejected with host resolves loopback address, which prevents relaying through a local proxy or tunnel.
  • MySQL, MariaDB & PostgreSQL: Range scans, range deletions and store purges run as a single unbounded statement, so on servers that enforce a statement timeout they abort on large accounts and tasks such as account deletion can never complete.
  • Network: local_port and local_ip report the address Stalwart is bound to rather than the address the client connected to when the connection arrives through a trusted proxy.
  • Task manager:
    • totalDeadline is not enforced on tasks that fail with a specific retry time.
    • Indexing tasks are dropped after maxAttempts failures, so a search store that is unavailable or overloaded leaves messages permanently missing from the index.
    • Indexing tasks are dropped when the document metadata read returns no data, which can happen on SQL read replicas that have not yet caught up with the primary.
    • The DNS management task republishes the DKIM records of retired keys that the DKIM rotation task had already removed from the zone.
  • Sieve: spamtest returns only 1 or 10 (and spamtest :percent only 0 or 100), so scripts cannot act on intermediate spam scores.
  • Spam filter: MIME_BAD is tagged whenever the declared Content-Type of an attachment is not byte identical to the type detected from its magic bytes.

Check binary attestation here

  •  

v0.16.18

17 Augustus 2026 om 23:45

[0.16.18] - 2026-08-17

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • Reporting: inboundReportMaxSize setting, which bounds the size of a decompressed inbound DMARC or TLS report (default 25MB).
  • RocksDB: cacheSize setting, which bounds the total memory shared by the block caches of every column family (default 128MB).

Changed

  • ASN & GeoIP: Default data source URLs now point at the ip-location-db GitHub releases, as the previously used npm packages are no longer updated. Existing installations keep their configured URLs and should update them following the ASN and GeoIP documentation.
  • JMAP: Identity/get keeps identities in sync with the account's e-mail addresses.
  • MTA: Queue scheduler no longer rescans the queue from the earliest pending event and coalesces bursts of delivery completions into a single scan.
  • RocksDB:
    • Column families are tuned for the access pattern of the data they hold.
    • Range iteration uses bounded iterators and no longer reads values when only keys were requested.

Fixed

  • JMAP:
    • Setting uploadTtl to 1ms triggers panic.
    • CalendarEvent/set does not assign organizerCalendarAddress nor send scheduling messages when an event is created with participants.
    • CalendarEvent/get omits isOrigin when it is listed explicitly in properties.
    • CalendarEventNotification/changes and FileNode/changes reject with cannotCalculateChanges the state that /get returned for an account with no change history.
    • CalendarEvent/set and ContactCard/set do not write a vanished tombstone for the previous CalDAV/CardDAV href when calendarIds or addressBookIds moves an item between collections.
  • CalDAV: Attendee addresses that percent-encode a display name into the mailto: URI are queued verbatim.
  • Calendar: Recurring events disappear from CalDAV time-range REPORTs and JMAP CalendarEvent/query results a few years after their first occurrence.
  • WebDAV:
    • When a file node references a parent folder that no longer exists, any request on a file collection panics.
    • MOVE on a folder honors a Depth header of 0 or 1 instead of always moving the whole subtree.
  • MTA:
    • DSN bounces are emitted with a malformed Message-ID wrapped in doubled angle brackets.
    • Delivery to any MX host whose name is an IDN A-label fails permanently.
    • Queue strategy and quota expressions that branch on source never match at enqueue.
    • MTA-STS:
      • Policies in testing mode are enforced, turning any TLS error into a permanent failure.
      • mx patterns published as U-labels never authorize the MX host they name.
    • DMARC:
      • Alignment compares identifiers in their A-label form.
      • External reporting addresses published as U-labels are rejected as unauthorized.
  • Spam filter:
    • Some rules misfire on internationalized addresses when the envelope and the headers spell the same domain in different label forms.
    • Punycode labels that do not re-encode to the label they came from are no longer decoded.
  • WebPush: Validate push URL and use application/octet-stream as Content-Type for encrypted payloads.
  • Directory:
    • Local group membership is cleared when the external directory is configured with a group claim or attribute that it does not return.
    • LDAP: Directories that store aliases as additional values of the primary address attribute provision no aliases.
    • Mail addressed to a domain alias is rejected with 550 Relay not allowed, unless the domain's primary name happened to be resolved earlier and is still cached.
  • RocksDB: bufferSize setting was applied to the unused default column family and had no effect.
  • Sieve: include statements fail to find system and user global scripts whose name contains uppercase characters.
  • Task manager: totalDeadline is measured from the time a task was created instead of its first failed attempt.

Check binary attestation here

  •  

v0.16.17

10 Augustus 2026 om 22:01

[0.16.17] - 2026-08-10

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • IMAP:
  • WebDAV: Range and If-Range header support on file downloads (RFC 7233) (#2377).
  • Spam filter: url_original expression variable for Url rules.

Changed

  • Memory allocator: Replaced the unmaintained jemallocator crate with tikv-jemallocator (contributed by @checkraisefold).
  • ACME registry: Use description as label property.

Fixed

  • MTA:
    • Certificates for domains publishing an enforcing MTA-STS policy are always validated, even in the fallback TLS strategy.
    • DSN delivery date uses wrong timestamp.
    • FUTURERELEASE HOLDUNTIL uses Unix timestamps instead of RFC 3339 date-times.
  • JMAP:
    • EmailSubmission/query filtering on undoStatus contradicts EmailSubmission/get, reporting held FUTURERELEASE submissions as final instead of pending.
    • EmailSubmission/get requests without an ids argument iterates the wrong index.
  • CardDAV: Accept: text/vcard version negotiation is ignored whenever another parameter such as q or charset follows version=.
  • Calendar: Server-side scheduling messages place the text/calendar part outside the multipart/alternative and disposed as an attachment.
  • Sharing: Accounts holding the impersonate permission never have their ACL grants collected, so shared items are never listed in JMAP sessions, CalDAV/CardDAV discovery or IMAP.
  • IMAP:
    • COPY/MOVE into a shared folder fails with NO [ALREADYEXISTS] when the destination account already holds the message, leaving the message in the source mailbox and clients in a retry loop.
    • BODYSTRUCTURE and ENVELOPE return MIME parameters, Content-Description, subjects and display names as raw UTF-8 even to sessions that never enabled UTF8=ACCEPT.

Check binary attestation here

  •  

v0.16.16

2 Augustus 2026 om 20:39

[0.16.16] - 2026-08-02

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • JMAP Email Delivery Push Notifications (draft-ietf-jmap-emailpush-03)
  • MTA: Allow System Sieve scripts to access orcpt during the DATA stage.

Changed

  • S3: accessKey can now be read from an environment variable or file.

Fixed

  • Meilisearch: Verify index existence using GET instead of creating a new task which times out on busy servers.
  • Branding: Stalwart logo flashes before the per-tenant logo is loaded on the login page.
  • Calendar: iMIP and alarm notification messages embed the default logo using bare LF line endings, producing a single 4247 octet line that strict SMTP relays reject with line too long.
  • DMARC: Failure reports state Identity-Alignment: none when a mechanism authenticated successfully but against an identity that is not aligned with the From domain.
  • Redis: Task and queue locks are never released after a worker dies, because failed lock attempts refresh the lock expiry.
  • Recovery mode: Download WebUI if missing.
  • Logging: The systemd journal tracer omits the parent span's fields.
  • MTA:
    • BDAT chunks sent without a valid MAIL FROM are answered with 552 5.3.4 Message too big for system instead of 503 5.5.1.
    • A maxMessageSize of 0 rejects every message with 552 5.3.4 Message too big for system instead of disabling the size limit.
  • Windows: Listeners bound to the unspecified IPv6 address ([::]), including all defaults, refuse IPv4 connections such as 127.0.0.1, since IPV6_V6ONLY is enabled by default on Windows.

Check binary attestation here

  •  

v0.16.15

27 Juli 2026 om 07:58

[0.16.15] - 2026-07-26

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • JMAP:
    • Email/copy should return alreadyExists when copying a message to a mailbox that already contains it.
    • Email/copy with onSuccessDestroyOriginal destroys the copy's creation id instead of the source Email id.
    • CalendarEvent/set does not generate a uid on create when the client omits it.
    • CalendarEvent/set does not refresh the updated property (iCalendar DTSTAMP) on create or update.
    • EmailSubmission/set rejects valid recipients whose domain is itself a public suffix (e.g. gov.in, co.uk).
    • Requests are rejected with notRequest when a method name contains a JSON-escaped solidus (e.g. Core\/echo).
  • MTA: Panic when MTA-STS is disabled and a remote MTA fetched /.well-known/mta-sts.txt.
  • Auth: Scoped credentials with SysApiKeyCreate or SysApiKeyUpdate permissions can regain its own account's full rights.
  • Web Push: Valid VAPID keys are rejected when PEM-encoded with explicit EC parameters, in SEC1 (EC PRIVATE KEY) format, or with a leading byte-order mark.
  • Encryption at rest: Appended messages are encrypted for accounts that did not opt in to encryptOnAppend.
  • Cache: Account caches silently discard entries larger than a single quick-cache shard, causing constant database rebuilds.
  • Registry: Id references (e.g. #certificate-...) fail to resolve on defaultCertificateId, defaultAdminRoleIds, listenerIds and publicKey.
  • Search: reindex drops calendar and contact index tasks for accounts with fewer than a full batch of items.
  • Migration: Abort --import when the target already contains data in the key range being imported.
  • Cluster: Broadcast subscriber re-subscribes after every message, losing bursts of cluster broadcasts during the reconnect window.
  • Enterprise: Per-tenant logo is not shown on the OAuth login password and OTP screens, which are served from the server's canonical host rather than the tenant domain.

Check binary attestation here

  •  

v0.16.14

20 Juli 2026 om 16:02

[0.16.14] - 2026-07-20

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • Use of Voluntary Application Server Identification (VAPID) in JMAP Web Push (RFC 9749).

Changed

Fixed

  • IMAP:
    • Mailbox object-quota only enforced in JMAP.
    • Pipelined STORE and EXPUNGE can execute out of order.
  • JMAP:
    • Read-only sharee cannot set isSubscribed on a shared mailbox.
    • Web Push payloads with Content-Encoding: aes128gcm should not be base64-encoded but sent as raw bytes.
    • Stale push subscription can block verification of a new one.
    • PushSubscription/set rejects the unpadded base64url keys the W3C Push API produces.
    • Email/import does not send push notifications for imported messages.
    • CalendarEvent/set silently ignores ifInState.
  • CalDAV: calendar-query REPORT returns empty calendar-data for JMAP-created events.
  • MTA:
    • DMARC is skipped when MAIL FROM SPF is unavailable.
    • queue_name variable not available in rate limiter expressions.
  • Calendar:
    • No expanded occurrences are returned for a daily recurrences crossing DST.
    • Uppercase MAILTO calendar addresses become invalid SMTP recipients.
    • Scheduling invitations on a shared, non-owned calendar fail with MAIL FROM unauthorized.
  • HTTP: Disable allowedEndpoints expression in recovery mode.
  • Telemetry: Tasks are serialized to the wrong store when using separate stores for telemetry and data.

Check binary attestation here

  •  

v0.16.13

12 Juli 2026 om 21:05

[0.16.13] - 2026-07-12

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • FreeBSD support.

Changed

Fixed

  • OAuth resource indicators: Accept imap, smtp, pop3 and sieve as valid resource indicators for OAuth access tokens.
  • PostgreSQL: Incomplete channel binding implementation.
  • JMAP:
    • VacationResponse: isEnabled reset to false whenever properties are changed.
    • Capabilities: Return RFC-3339-conformant UTCDate literals in capabilities: min 0001-01-01T00:00:00Z, max 9999-12-31T23:59:59Z.
  • Directory: Update local groups only when the external directory includes a group attribute.
  • DNS Management:
    • CAA management deletes too third-party CAA entries.
    • Multiple provider fixes (see dns-update crate changelog).
  • Reject invalid duration values (e.g. 1h30m).
  • Branding: Custom logos for domains do not work.
  • Sieve: add Received headers to auto-generated messages and detect loops.
  • MTA: Resume queue processing does not work.
  • Misconfigured in-memory store cannot be recovered in recovery mode.

Check binary attestation here

  •  

v0.16.12

6 Juli 2026 om 14:55

[0.16.12] - 2026-07-06

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • DANE: Treat DNSSEC bogus as a temporary failures to prevent downgrade attacks.
  • OIDC provider:
    • ECDSA private key support for SEC1 format.
    • Allow ports in redirect_uri for loopback addresses.
  • OIDC directory:
    • Removing a user from all groups does not sync the changes correctly.
    • Fetch name and group claims from userinfo endpoint when missing from the JWT token.
  • PostgreSQL: Include error chain in error messages.
  • Prometheus: event counters are exported with incorrect metric names.
  • Registry: Changing the type of an existing account from user to group panics.
  • Masked emails: Return UnknownRecipient only for disabled or expired masked emails.
  • IDN: sanitize_email rejects valid Punycode domains.
  • Auto-ban: IP block expiration ignores per-reason ban durations.
  • Meilisearch: Limit the text search scope using attributesToSearchOn.
  • CalDAV: calendar-query REPORT returns invalid HTTP 404 when no events match the query.
  • Snowflake past id generation fails when the provided duration is longer than 4 years.
  • Calendar scheduling: Wrong RSVP base URL is used.
  • Network listener: Accept loop spins all CPU cores with no back-off when the process hits EMFILE (too many open files).
  • Cluster: Broadcast MTA queue refresh events to all nodes.

Check binary attestation here

  •  

v0.16.11

25 Juni 2026 om 12:51

[0.16.11] - 2026-06-25

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • Encryption-at-rest: Support for AES-256-GCM and ChaCha20-Poly1305 for S/MIME (#161).
  • S3: Support for allowInvalidCerts option to allow connecting to S3 endpoints with invalid TLS certificates.
  • Redis Sentinel support as an in-memory store and cluster coordinator backend (#2430).

Changed

Fixed

  • DANE: Verify DNSSEC is supported by the resolver before attempting to validate TLSA records.
  • TLS: Update search index when file-backed certificates are refreshed.
  • JMAP: Principal/query returns broad results when a name or email filter cannot be resolved.
  • Webhooks: event IDs collide for same event type emitted in the same second.

Check binary attestation here

  •  

v0.16.10

21 Juni 2026 om 17:56

[0.16.10] - 2026-06-21

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • International Domain Names (IDN) support (#207).
  • OAuth:
  • HTTP: Add redirectRoot option to Http object to allow redirecting requests to the root path to a different path (e.g. /account).
  • ACME: reuseKey option to allow reusing private keys in renewals.
  • IMAP:

Changed

Fixed

  • JMAP conformance (pass the jmap-test-suite tests):
    • Methods are only available if their capability is in using.
    • Reject requests that do not specify application/json in the Content-Type header.
    • Require accountId argument on requests.
    • Return unparsable ids in notFound / notUpdated / notDestroyed / notCopied instead of dropping them.
    • Default calendars and address books are not subscribed by default.
    • */set: Unchanged immutable id property is rejected on update.
    • */query and */queryChanges: nullrejected asnotRequest`.
    • Email/query:
      • Improper anchor handling.
      • Total miscount when collapseThreads is enabled.
      • Wrong sort order on hasKeyword, allInThreadHaveKeyword, and someInThreadHaveKeyword conditions.
      • Non-standard header values are not searchable.
    • Email/copy: Take the source message id from the value's id property.
    • Email/set: Bump reference-resolution max_depth from 1 to 2.
    • Email/import: Reject blobs that do not contain valid messages.
    • EmailSubmission/set: return sendAt and undoStatus in the created response.
    • Mailbox/set: Return alreadyExists instead of invalidProperties when creating a mailbox with an existing name.
    • SearchSnippet/get: incorrect response structure.
    • Thread/changes: emit a container delete when a thread becomes empty.
    • VacationResponse/set: incorrect singleton handling.
  • IMAP: Discard oversized non-synchronizing literals (#2768).
  • DANE: Improper TLSA record validation (#2328 - credits to @vdukhovni).
  • OIDC: Add default domain name to groups that are not email addresses.
  • RocksDB: Enable blob garbage collection to reclaim disk space from deleted blobs.
  • Sieve: include statements ignore capitalisation of sub-script names (#1643)
  • Cache: Invalidate negative email caches when an account is created.
  • Troubleshoot tool: Use the configured source IP address when connecting to remote servers (#2867).

Check binary attestation here

  •  

v0.16.9

16 Juni 2026 om 08:01

[0.16.9] - 2026-06-15

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • ACME: Allow specifying a preferred certificate chain.

Changed

Fixed

  • JMAP: */changes methods leak ids of non-shared objects (reported by @5ud0er).
  • Sieve: Do not allow invalid certs in http_header function.
  • FoundationDB: Fix read version cache expiration logic.
  • MTA: Re-scheduling or editing a queued message reports success but persists nothing for recipients in a non-default virtual queue.
  • CardDAV: Version requests included in address-data are ignored.
  • ACME: Add freshness check when renewing certificates.
  • Autodiscover v2: Read email address from query parameters.
  • Sieve: Do not keep copies of redirected messages when keep is not specified.
  • Registry: Object ids are parsed as numbers.

Check binary attestation here

  •  

v0.16.8

6 Juni 2026 om 20:33

[0.16.8] - 2026-06-06

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

  • OAuth: Rework access tokens to an AES-256-GCM-SIV AEAD format that carries the account name for proxy routing.
  • Added more internal TLDs to the domain validation.

Fixed

  • MTA:
    • Sub-addressing with external directories returns 550 Mailbox not found.
    • Disabled aliases continue receiving messages.
  • JMAP for File Storage: FileNode/get returns a stale state string.
  • Make SieveSystemInterpreter.defaultReturnPath and MtaQueueQuota.match optional expressions.
  • Rate limiter panics when periods under 1 second are used.
  • CalDAV/CardDAV: Calendar events, contacts, calendars and address books deleted via JMAP do not write a vanished tombstone.
  • DNS updater: bump to dns-update-v0.5.1.

Check binary attestation here

  •  

v0.16.7

29 Mei 2026 om 09:41

[0.16.7] - 2026-05-28

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • Log rejected messages to tracing store.
  • MTA:
    • Always update next DSN notify times.
    • Expand lists and resolve catch-all addresses when building autogenerated messages.
  • Sharing: Includes resource that themselves carry a direct ACL grant and are leaves.
  • Tasks cannot be deleted in OSS builds.
  • Directory: Per-domain external directory resolution fails.
  • DNS updater: Keep external TXT records when updating RRSet.
  • HTTP: Reject requests from blocked IPs when Keep-Alive is enabled.

Check binary attestation here

  •  

v0.16.6

20 Mei 2026 om 10:32

[0.16.6] - 2026-05-20

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • Added 58 new DNS provider integrations (see dns-update crate for details).
  • DNS updater: Log DNS record types and values.
  • Sieve: Allow User Sieve scripts to access orcpt.
  • MTA: Log when messages are rejected or discarded by the spam classifier.

Changed

Fixed

  • DAV: acl-principal-prop-set REPORT enforced the wrong privilege.
  • JMAP: Thread/get did not filter by per-mailbox ACLs on shared accounts.
  • IMAP: UID FETCH N:* could miss messages moved into a SELECTed mailbox by another connection.
  • DNS updater:
    • Skip v=spf1 a -all records for apex domains.
    • RFC2136 TSIG: regression related to multiplexer.
    • Route53: Chunk TXT records when they exceed 255 characters.
  • ACME:
    • Update defaultCertificateId when renewing a certificate that is currently set as default.
    • Perform DNS-01 authorizations sequentially to avoid race conditions in some DNS providers.
  • Allow internal TLDs and special characters in e-mail addresses.
  • Websocket: Perform case insensitive matching during upgrade.
  • LDAP: Synchronize accounts when expanding mailing list recipients.
  • Sieve: replace action adds an extra From header.
  • ACL: Orphaned ACL entries for deleted accounts cause JMAP session errors.

Check binary attestation here

  •  

v0.16.5

11 Mei 2026 om 18:47

[0.16.5] - 2026-05-11

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • is_ip_in_cidr expression function for CIDR matching.

Changed

  • Bump mail-auth to 0.9 (which bumps hickory-resolver to 0.26).
  • Deprecated RFC2136 SIG(0) support as it is no longer supported by hickory.

Fixed

  • JMAP:
    • Patching ids containing digits in JSON Pointers fails.
    • Patching nested objects with null values fails.
  • External directories:
    • SQL: Return Failed instead of Error when the query returns no results.
    • LDAP: Impersonation fails when the user has not logged in before.
  • Network: Attempt binding to IPv4 when binding to IPv6 fails with EAFNOSUPPORT error.
  • Bootstrap: Timeout after 30 seconds when probing the data store.
  • HTTP: Use permissive CORS headers for .well-known endpoints.
  • ACME:
    • Include apex domains when requesting certificates for subdomains.
    • Use the public suffix list to determine the zone name when no origin is provided.
  • MTA:
    • Allow rescheduling recipients with permanent failures.
    • Process reports using original RCPT before rewriting.
  • Autodiscover v2 endpoint unreachable.
  • DNS update (via dns-update crate):
    • OVH + Google Cloud DNS: Fix FQDN handling for MX and SRV records.
    • Route53: Fix changeset error resolution.
    • deSEC: Use empty subname for apex records instead of @, which the API rejects.
    • Cloudflare: Wrap TXT record content in double quotes (RFC 1035) to suppress dashboard warnings.
  • iCalendar/JSCalendar (via calcard crate):
    • Support STATUS:CANCELLED mapping from VTODO to JSCalendar.
    • Fixed duration parsing for zero duration PT0S.

Check binary attestation here

  •  

v0.16.4

5 Mei 2026 om 13:28

[0.16.4] - 2026-05-05

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

Fixed

  • Live tracing in community and OSS versions.
  • Timezone changes from the AccountSettings object return invalidProperties.
  • mail-parser panic with certain messages containing corrupted attachments.
  • Pagination by anchor for queued messages, tasks and metrics.
  • Spam filter: Use original instead of rewritten RCPT on checks.
  • JMAP:
    • References in nested objects not resolved.
    • AddressBook/query fetches wrong resources.
  • Import tool fails to restore registry entries.
  • FDB: Allow multiple FoundationDB instances in the same process.
  • Autoconfig: Return %EMAILADDRESS% when no email address is provided.
  • Quota: Include Sieve scripts in quota recalculations.

Check binary attestation here

  •  

v0.16.3

30 April 2026 om 19:31

[0.16.3] - 2026-04-30

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

Changed

  • Replaced STALWART_HTTPS_PORT with STALWART_PUBLIC_URL.
  • App Passwords now begin with app_ instead of app to avoid issues with some clients that do not support spaces in passwords.

Fixed

  • Directory:
    • Invalidate caches when group memberships change on an external directory.
    • OIDC: errors instead of "failed to decode token".
    • OIDC: Recovery admin access.
    • User impersonation.
  • Tasks:
    • Delete locked tasks.
    • Queue pagination by anchor.
  • Log viewer: All events show as INFO.
  • Registry: Allow changing object variants.
  • Node id renewal.
  • DNS Updater: Fix Route53 serialization format.

Check binary attestation here

  •  

v0.16.2

28 April 2026 om 17:30

[0.16.2] - 2026-04-28

If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • OIDC: Fallback to userinfo endpoint when JWT token does not contain an email claim.
  • S3: verifyAfterWrite option to verify that objects have persisted after writing.

Changed

  • Allow HTTP to be used for configuring the server.

Fixed

  • LDAP: Generate valid credentialId when there are password changes.
  • TLS: Disable cipher suited option disables wrong ciphers.
  • DNS Updater:
    • BunnyDNS: Use subdomain as name of record instead of FQDN.
    • RFC2136: Chunk TXT records.
  • Skip invalid entries in log files.

Check binary attestation here

  •  

v0.16.1

25 April 2026 om 09:35

[0.16.1] - 2026-04-25

This version includes multiple breaking changes. If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • OIDC: Extract username from JWT token.
  • system('node_hostname') and system('node_role') expression variables to retrieve the local node hostname and cluster role respectively.

Changed

Fixed

  • JMAP:
    • Invalid receivedAt headers after importing (#2939).
    • Sorting order issues when emails lack receivedAt headers.
  • IMAP: Fix BINARY fetch responses (#2940).
  • WebDAV: Fix ACL validation for target folders.
  • ACME: Allow requesting apex domain certificates.
  • Hostname issues:
    • Accept RFC 6761 reserved TLDs during bootstrap.
    • Allow hostnames without TLDs in remote server settings.
  • Reverse proxy issues.
  • OSS builds.
  • DNS Updater:
    • RFC2136: TSIG secret not base64 decoded.
    • Google DNS: Chunk TXT records when they exceed 255 characters.
    • Cloudflare:
      • Fix CAA record updates.
      • Check zone subdomains when finding zones

Check binary attestation here

  •  

v0.16.0

20 April 2026 om 19:27

[0.16.0] - 2026-04-20

This version includes multiple breaking changes. If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.

Added

  • Web UI rewritten from the ground up using the JMAP management API, featuring a refreshed design and addressing 76 enhancement requests and bug fixes.
  • CLI rewritten from the ground up to use the JMAP management API.
  • Security enhancements:
    • Password strength enforcement using the zxcvbn algorithm
    • Password expiration, rotation policies and IP address restrictions for user accounts
    • App Passwords with limited access (#1609), labels (#2255), IP address restrictions and expiration dates
    • API keys with limited access, labels, IP address restrictions and expiration dates
    • Auto-ban comments and details about the triggering event (#1321)
    • Auto-ban expiration after a configurable time period (#964)
  • DNS Management:
  • DKIM:
    • Automatic DKIM key generation, rotation and DNS management (#368 #961)
    • Store DKIM keys in the database (#1264)
    • Ignore insecure signatures when verifying DKIM (#1068 #467)
  • ACME/TLS:
    • DNS-PERSIST-01 ACME challenge support (#2837)
    • Renew certificates on demand, view certificate details (#675 #1162 #2566)
    • CAA record support (#468) with accounturi parameter (#1933)
    • TLSA records publishing restricted to 3 1 1 and 2 1 1 (#2193)
  • OIDC and OAuth:
    • JWT token validation without requesting userinfo from the OIDC provider.
    • Audience (aud) claim (#2603) and scope validation support.
    • Groups support (#1448)
    • RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients
  • LDAP:
    • Separate filter for groups (#1841)
    • Improve support for OpenLDAP schemas (#760)
    • Improve and simplify LDAP settings (#2194 #2174)
  • Directory:
    • Masked email addresses for enhanced privacy (Enterprise)
    • Domain aliases (#583)
    • E-mail alias descriptions and option to disable aliases (#506)
    • Account archiving and un-deletion (#2767) (Enterprise)
    • Per-domain directory backends (Enterprise)
  • Account configuration and discovery:
  • Sieve: Allow deactivating scripts without deleting them (#1251).
  • Tracing: Enable events only mode (#2276)
  • Clustering:
    • Automatic cluster node ID generation and management.
    • Unified cluster management (#960)
    • Outbound MTA role (#1692)

Changed

  • Replaced REST API with JMAP API (#2262 #959 #1480)
  • Removed support for Authenticated Received Chain (ARC) sealing (learn more).
  • Directory: Removed smtp, imap and memory directory backends.
  • Use aws-lc for cryptographic operations instead of ring.
  • Use rustls-platform-verifier for TLS certificate verification instead of webpki (#247).

Fixed

  • Directory:
    • Cannot remove built-in "admin" role from user once it was assigned (#1467)
    • Delete associated records (#963)
    • Updated Role permissions not applied (#2038)
    • Recreated account cannot log in until server is restarted (#1469)
    • Subaddressing does not work for groups (#475)
    • New LDAP aliases are rejected (#1318).
    • Validate account and group names (#2209)
  • MTA:
    • RCPT TO stage settings improvements (#2217 #394)
    • Relay to IP addresses (#838)
    • Duplicate delivery inverted check
    • SASL challenge responses include invalid Go ahead text
  • JMAP:
    • Fix inMailboxOtherThan query logic.
    • Fix hasAttachment search field (#2778)
  • IMAP:
    • Increment argument max length to 8000 bytes
    • ACL: Add RIGHTS capability (#2762)
    • ACL: Fix ACL SET permission override.
  • WebDAV:
    • Return 304 NOT_MODIFIED on If-None-Match
    • Use RFC 2616 instead of RFC 1123 for date formatting
    • Fix ACL container/item mismatch in reports.
    • CalDAV: Allow organized properties to be present in PUT requests if they are equal to the existing ones.
    • CalDAV: Enforce cumulative iCalendar instances cap in CalDAV free-busy REPORT handler
  • Configuration: Prefix parsing issues (#2495)
  • OIDC: JWKS Exposes Symmetric Signing Key
  • SQLite: Fix thread pool exhaustion.
  • PostgreSQL: Use clean recycling method on connection pool
  • Meilisearch: Make id sorteable.
  • ACME: Fix wrong origin for subdomain updates (#2360)
  • Spam filter: Skip invalid messages during training.
  • Calendar: Include minutes in localized invite templates (#2828)
  • HTTP: Fix 204 CORS preflight responses

Check binary attestation here

  •  
❌