> ## Content Index
> Fetch the complete content index at: https://www.process-one.net/llms.txt
> Use this file to discover other available public pages before exploring further.

# 🚀 ejabberd 25.10
- URL: https://www.process-one.net/blog/ejabberd-25-10/
- Published: 2025-10-28T18:00:38.000Z
- Updated: 2025-10-31T14:11:56.000Z
- Description: We are pleased to announce a new ejabberd release: ejabberd 25.10, two months after the previous one, including several bugfixes, and many improvements for administrators and developers.
- Author: Jérôme Sautret
- Tags: ejabberd, Release, XMPP

**Release Highlights:**

- **[Added more Ad-Hoc Commands from XEP-0133](#adhoc)**
- **[Updated support for XEP-0317 Hats](#hats)**

If you are upgrading from a previous version, there are no mandatory changes in SQL schemas, configuration, API commands or hooks.

**Other contents:**

- **[New option archive\_muc\_as\_mucsub in mod\_mam](#mucsub)**
- **[Removed support for Erlang/OTP older than 25.0](#erlang25)**
- **[Support for the new Erlang maybe expression](#maybe)**
- **[Rename New SQL schema to Multihost, and Default to Singlehost](#multihost)**
- **[Improved GitHub Workflows](#workflows)**
- **[Acknowledgments](#ack)**
- **[Improvements in ejabberd Business Edition](#ebe)**
- **[ChangeLog](#changelog)**
- **[ejabberd 25.10 download & feedback](#download)**

Below is a detailed breakdown of the improvements and enhancements:

## New option archive\_muc\_as\_mucsub in mod\_mam

When this option is enabled incoming groupchat messages for users that have MucSub subscription to a room from which message originated will have those messages archived after being converted to mucsub event messages.

## Removed support for Erlang/OTP older than 25.0

The [ejabberd 24.12 release announcement](https://www.process-one.net/blog/ejabberd-24-12/#erlang25) explained that support for Erlang/OTP older than 25.0 was discouraged, it would be deprecated in future releases, and completely removed sometime after ejabberd 25.01\. That explanation was mentioned several times in the subsequent ejabberd releases.

The initial reason to require Erlang/OTP 25 was that this version is the lowest we can easily use nowadays for running the [CI tests](https://github.com/processone/ejabberd/actions/workflows/ci.yml?ref=process-one.net).

Other reasons to remove support for Erlang lower than 25 are: to support `maybe` expression, and to remove duplicate code.

In order to support both new and very old Erlang/OTP versions, ejabberd source code included many duplicate code. All that duplicate code that is nowadays useless will be removed in a future ejabberd release.

## Support for the new Erlang 'maybe' expression

The new `maybe` expression is supported since Erlang/OTP 25 (requires being enabled), and it is enabled by default since 27.

Now that ejabberd requires Erlang/OTP 25, and it enables the `maybe` expression, this can be used freely in ejabberd source code and modules.

See:

- Erlang Documentation: [maybe Expression](https://www.erlang.org/doc/system/expressions.html?ref=process-one.net#maybe)
- [EEP 49: Value-Based Error Handling Mechanisms](https://www.erlang.org/eeps/eep-0049?ref=process-one.net)

## Rename 'New' SQL schema to 'Multihost', and 'Default' to 'Singlehost'

When ejabberd first got support for SQL storage, it only supported one vhost, so it made sense to **not** store the host in the SQL tables. Additionally, the SQL schema in ejabberd followed that of jabberd14, which didn't support multiple vhosts either.

When ejabberd got support for multiple vhosts, if several of them want to use SQL storage, the solution is to configure a different SQL database for each vhost using the `host_config` toplevel option.

However, when there are many vhosts configured in ejabberd, all of them using SQL storage, it is preferable to setup one single SQL database, and store the vhost in the tables. When that feature was added to ejabberd, it got the name of "new SQL schema". And the previous SQL schema was called "legacy", "old", and nowadays "default".

The problem with the terms "default" and "new" is that they are circumstantial, and do not really describe the schema features or purposes.

Now those terms have been renamed:

- "default SQL schema" ⟹ "singlehost SQL schema"
- "new SQL schema" ⟹ "multihost SQL schema"

Right now all names are supported, the previous (obsolete) and the renamed (preferred). No changes are needed in your existing configuration file or building instructions, but it is preferable if you can update your setup to the new terms:

When preparing configuration, the old and new arguments are:

```
./configure --enable-new-sql-schema
./configure --enable-multihost-sql-schema

```

When configuring ejabberd, the old and new toplevel options are:

```
new_sql_schema: true
sql_schema_multihost: true

```

When developing source code, the old and new functions are:

```
ejabberd_sql:use_new_schema()
ejabberd_sql:use_multihost_schema()

```

## New API Commands

Several ejabberd modules implement new API Commands, most of them inspired by [XEP-0133](https://xmpp.org/extensions/xep-0133.html?ref=process-one.net):

- `ejabberd_admin`:  
  - [restart\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#restart%5Fkindly)
- [mod\_admin\_extra](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fadmin%5Fextra):  
  - [count\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#count%5Fbanned)
  - [list\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#list%5Fbanned)
- [mod\_announce](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fannounce):  
  - [announce\_motd\_delete](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fdelete)
  - [announce\_motd\_get](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fget)
  - [announce\_motd\_set\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fset%5Fonline)
  - [announce\_motd\_update](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fupdate)
  - [announce\_send\_all](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fsend%5Fall)
  - [announce\_send\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fsend%5Fonline)
- [mod\_muc\_admin](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Fadmin):  
  - [muc\_get\_registered\_nick](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#muc%5Fget%5Fregistered%5Fnick)
  - [muc\_get\_registered\_nicks](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#muc%5Fget%5Fregistered%5Fnicks)

## Added more Ad-Hoc Commands from XEP-0133

[XEP-0133](https://xmpp.org/extensions/xep-0133.html?ref=process-one.net#usecases) describes 31 administrative tasks that should be available as ad-hoc commands.

ejabberd already implemented many of those ad-hoc commands in [mod\_configure](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconfigure), but there were a few missing that nowadays are fairly easy to implement: this new ejabberd release supports all of them... except 5.

The five ad-hoc commands from XEP-0133 that are not supported are:

- `6. Get User Password`, because it was already retracted in the XEP and should not be implemented
- `12. Edit Whitelist`, because the corresponding feature is not implemented in ejabberd
- `27. Set Welcome Message`, because in ejabberd this message is set in the configuration file, option `welcome_message` of [mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister)
- `28. Delete Welcome Message`, for similar reason
- `29. Edit Admin List`, because in ejabberd the administrative rights to accounts are granted in the configuration file, toplevel option `acl`.

On the other hand, ejabberd implements more than [200 API commands](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) in all over its source code, providing those and many other administrative tasks. And you can execute those API commands using the command line, ReST calls, XML-RPC, WebAdmin, ... and ad-hoc commands too!!! See the available [API frontends](https://docs.ejabberd.im/developer/ejabberd-api/?ref=process-one.net#api-frontends).

Nowadays, all the ad-hoc commands described in XEP-0133 have a similar API command in ejabberd that you can execute using ad-hoc commands too:

| Ad-hoc command in XEP-0133        | Status in ejabberd 25.10 | Equivalent [API command](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net)                                     |
| --------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Add User                          | 〽️ (no vCard arguments)  | [register](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#register)                                          |
| Delete User                       | ✅                        | [unregister](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#unregister)                                      |
| Disable User                      | ✅                        | [ban\_account](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#ban%5Faccount)                                 |
| Re-Enable User                    | ✅                        | [unban\_account](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#unban%5Faccount)                             |
| End User Session                  | 〽️ (argument)            | [kick\_session](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#kick%5Fsession)                               |
| Get User Password (retracted)     | ▶️ (retracted)           | [check\_password](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#check%5Fpassword)                           |
| Change User Password              | ✅                        | [change\_password](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#change%5Fpassword)                         |
| Get User Roster                   | 〽️ (result syntax)       | [get\_roster](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Froster)                                   |
| Get User Last Login Time          | ✅                        | [get\_last](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Flast)                                       |
| Get User Statistics               | ✅                        | [user\_sessions\_info](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#user%5Fsessions%5Finfo)                |
| Edit Blacklist                    | ▶️                       | [add\_blocked\_domain](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#add%5Fblocked%5Fdomain)                |
| Edit Whitelist                    | ❌                        | \-                                                                                                                                           |
| Get Number of Registered Users    | ✅                        | [stats](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stats)                                                |
| Get Number of Disabled Users      | ✅                        | [count\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#count%5Fbanned)                               |
| Get Number of Online Users        | ✅                        | [stats](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stats)                                                |
| Get Number of Active Users        | ✅                        | [status\_num](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Fnum)                                   |
| Get Number of Idle Users          | ✅                        | [status\_num](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Fnum)                                   |
| Get List of Registered Users      | ✅                        | [registered\_users](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#registered%5Fusers)                       |
| Get List of Disabled Users        | ✅                        | [list\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#list%5Fbanned)                                 |
| Get List of Online Users          | ✅                        | [connected\_users](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#connected%5Fusers)                         |
| Get List of Active Users          | ✅                        | [status\_list](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Flist)                                 |
| Get List of Idle Users            | ✅                        | [status\_list](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Flist)                                 |
| Send Announcement to Online Users | ✅                        | [announce\_send\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fsend%5Fonline)            |
| Set Message of the Day            | ✅                        | [announce\_motd\_set\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fset%5Fonline) |
| Edit Message of the Day           | ✅                        | [announce\_motd\_update](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fupdate)            |
| Delete Message of the Day         | ✅                        | [announce\_motd\_delete](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fdelete)            |
| Set Welcome Message               | ▶️                       | (option welcome\_message in [mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister))       |
| Delete Welcome Message            | ▶️                       | (option welcome\_message in [mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister))       |
| Edit Admin List                   | ▶️                       | (option [acl](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#acl))                                               |
| Restart Service                   | ✅                        | [restart\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#restart%5Fkindly)                           |
| Shut Down Service                 | ✅                        | [stop\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stop%5Fkindly)                                 |

Status legend:

- ✅ Implemented in ejabberd exactly as XEP-0133 describes it
- 〽️ Implemented with same command name, but different arguments or results
- ▶️ Not implemented as XEP-0133 says, but we have an alternative solution
- ❌ Not implemented in ejabberd in any way

## Updated support for XEP-0317 Hats

Support for [XEP-0317 Hats](https://xmpp.org/extensions/xep-0317.html?ref=process-one.net) is improved from 0.2.0 to the latest 0.3.1.

Previously, the XEP lacked some use cases, and ejabberd implemented them as custom additional features, as documented in [MUC Hats](https://docs.ejabberd.im/tutorials/muc-hats/?ref=process-one.net). Now that the XEP includes all those additions, ejabberd strictly follows XEP-0317 version 0.3.1.

## Improved GitHub Workflows

The ejabberd git repository contains [several GitHub Workflows](https://github.com/processone/ejabberd/tree/master/.github/workflows?ref=process-one.net) to test automatically the source code with static and dynamic tools, build installers and containers.

Those workflows recently got several improvements:

- Run agnostic-database tests only once, not for every backend
- Add local composite actions to manage ejabberd and databases
- Reorganize steps in the CI workflow to run in parallel jobs
- Use ARM runners to build ARM installers and containers, no need for cross compiling
- Use ARM runners instead of x86 when possible, as they run faster
- Cache dependencies and download from CDNs when possible

With all those improvements, the workflows complete (or give some error report) in less than 10 minutes, instead of the 30 minutes that were common before.

For details about those changes, check [PR 4460](https://github.com/processone/ejabberd/pull/4460?ref=process-one.net)

## Acknowledgments

We would like to thank the contributions to the source code provided for this release by:

- [Guus der Kinderen](https://github.com/guusdk?ref=process-one.net) for update XMPP-Interop-Testing
- [Holger Weiß](https://github.com/weiss?ref=process-one.net) for mod\_push cosmetic changes
- [marc0s](https://github.com/marc0s?ref=process-one.net) for the new `push_send_notification` hook
- [Pouriya Jahanbakhsh](https://github.com/pouriya?ref=process-one.net) for pass HTTP headers from WS to C2S connection
- [Yurt Page](https://hosted.weblate.org/user/yurtpage2/?ref=process-one.net) for updating the Russian translation

And also to all the people contributing in the ejabberd chatroom, issue tracker...

## Improvements in ejabberd Business Edition

Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following changes:

- The `bulk_roster_update` API command now accept a list of groups.
- The `mod_dedup` module has been improved to handle received markers. This module was added in 4.2508 to prevent both delivery and storage of duplicates in archive.
- Fixed a case where a mobile client was not able to retrieve all the messages received while it was offline after a temporarily loses of its data connection.

##  ChangeLog

This is a more complete list of changes in this ejabberd release:

#### Ad-hoc Commands

- `mod_configure`: New ad-hoc commands that were missing from XEP-0133
- `mod_adhoc_api`: Add support for asynchronous command calling
- `mod_adhoc_api`: If argument is a list of jids, type is `jid-multi`
- `mod_adhoc_api`: If field has several values, type is `text-multi`

#### API Commands

- Add commands argument type `binary_or_list`
- `mod_http_api`: Format sub elements for tuples from maps
- `mod_admin_extra`: Improve roster API commands documentation
- `mod_announce`: New API commands, reusing existing ad-hoc functions
- `ejabberd_admin`: New API command `restart_kindly`, improve `stop_kindly`
- `mod_admin_extra`: New API commands `list_banned` and `count_banned`
- `mod_admin_extra`: Improve API command `status_list`: support for status to be a list
- `mod_muc_admin`: New API commands `muc_get_registered_nick` and nicks ([#4468](https://github.com/processone/ejabberd/issues/4468?ref=process-one.net))
- Use `mod_private:del_data` in `unban_account` API command

#### Configuration

- Rename `New` SQL schema to `Multihost`, and `Default` to `Singlehost` ([#4456](https://github.com/processone/ejabberd/issues/4456?ref=process-one.net))
- Add config transformer from `use_new_schema` \-> `sql_multihost_schema`
- `mod_sip`: Fix problem parsing `via` in `yconf` library ([#4444](https://github.com/processone/ejabberd/issues/4444?ref=process-one.net))

#### Erlang/OTP support

- Enable feature `maybe_expr` in the compiler for Erlang/OTP 26 ([#4459](https://github.com/processone/ejabberd/issues/4459?ref=process-one.net))
- Enable feature `maybe_expr` also in the runtime for Erlang/OTP 25
- Runtime: Remove Erlang 24 which won't work anymore with `maybe_expr`
- Remove `EX_RULE` and `EX_STACK` macros only used with ancient erlang

#### GitHub Workflows

- CI: Bump XMPP-Interop-Testing/xmpp-interop-tests-action ([#4469](https://github.com/processone/ejabberd/issues/4469?ref=process-one.net))
- CI: Don't care to include commit details in the CT logs HTML page
- CI and Runtime: Reorganize steps to run in parallel, and ARM runner ([#4460](https://github.com/processone/ejabberd/issues/4460?ref=process-one.net))
- Add local composite actions to manage ejabberd and databases
- Container: Build ARM in native runner instead of QEMU, merge and clean
- Installers: Generate ARM installers in native runner
- Tests: Run agnostic-database tests only once, not for every backend
- Tests: The odbc backend is not actually used in Commont Tests
- Weekly: New workflow that condenses CI, test all erlang without caching

#### Installers and Containers

- Bump Erlang/OTP version to 27.3.4.3 in installers and container
- Bump Expat 2.7.3, OpenSSL 3.5.4, unixODBC 2.3.14 in installers

#### MUC

- `mod_mam`: New option `archive_muc_as_mucsub`
- `mod_muc`: Check if room is hibernated before calling mod\_muc process
- `mod_muc`: Update implementation of XEP-0317 Hats to version 0.3.1 ([#4380](https://github.com/processone/ejabberd/issues/4380?ref=process-one.net))
- `mod_muc`: Make mod\_muc\_sql properly handle new hats data ([#4380](https://github.com/processone/ejabberd/issues/4380?ref=process-one.net))
- `mod_muc_room`: Don't require password if user is owner of room
- `mod_muc_admin`: Use in WebAdmin the new API commands that get nick registers

#### Core and Modules

- `ejabberd_http_ws`: Pass HTTP headers from WS to C2S connection ([#4471](https://github.com/processone/ejabberd/issues/4471?ref=process-one.net))
- `ejabberd_listener`: Properly pass `send_timeout` option to listener sockets
- `ejabberdctl`: When ping returns pang, return also status code 1 ([#4327](https://github.com/processone/ejabberd/issues/4327?ref=process-one.net))
- `ext_mod`: Print module status message after installation
- `misc`: json\_encode should always call json with our filter
- `mod_admin_update_sql`: Use same index name than when creating database
- `mod_block_strangers`: Clarify `access` and `captcha` documentation ([#4221](https://github.com/processone/ejabberd/issues/4221?ref=process-one.net))
- `mod_http_upload`: Encode URL before parsing, as done before `bba1a1e3c` ([#4450](https://github.com/processone/ejabberd/issues/4450?ref=process-one.net))
- `mod_private`: Add `del_data/3`, `get_users_with_data/2`, `count_users_with_data/2`
- `mod_pubsub`: Don't catch `exit:{aborted, _}` inside mnesia transactions
- `mod_push`: Run new hook `push_send_notification` ([#4383](https://github.com/processone/ejabberd/issues/4383?ref=process-one.net))
- WebAdmin: Respect newline and whitespace characters in results

### Full Changelog

[https://github.com/processone/ejabberd/compare/25.08...25.10](https://github.com/processone/ejabberd/compare/25.08...25.10?ref=process-one.net)

##  ejabberd 25.10 download & feedback

As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net).

The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/).

For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net).

The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net).

If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net).