ejabberd 16.06

We are proud to introduce our new ejabberd release, ejabberd 16.06. As usual it includes many bug fixes, but also several improvements.

The big improvement in this release is a new Access Control List (ACL) infrastructure. ACL rules are used in ejabberd config file to define fine-grained access to ejabberd features.

In ejabberd 16.06, the ACL configuration has been much improved to make it both simpler to use and easier to read. Moreover, ACL and access rules are not mandatory anymore when configuring access restrictions for a feature or a module: You can just inline the user, for example, making small configuration much easier to setup properly.

To make you even more comfortable, our new code is still supporting the old syntax and you can mix old and new syntax. It means that you can still use your existing configuration file and that you can migrate incrementally, as needed.

The new ACL syntax

New access rule will look like this:

    - allow: admins
    - deny: blocked
    - allow:
      - user: "peter@server.com"
      - ip: ""
    - allow: moderators

This is an example definition for my_access rule. It is composed of four groups. They are evaluated from top to bottom order. the first with all listed acl rules evaluated as true is used as result. If none of them matches, evaluation fallback to default value deny. Above definition can be parsed as: if user belongs to ACL definition admins, return allow, if not, and user belongs to ACL definition blocked, return deny. otherwise for user “peter@server.com” when connected from ip: “” return allow, and for users in ACL definition moderators return allow as well, in all other cases return deny.

We can see in this example two new additions that were introduced in this rewrite:

  • you can now directly specify ACL definitions inside access rules (you no longer will be required to define ACL rules for each case)
  • you now have the ability to require a match on several ACL rules types at this same time (in the example: ip and user).

You can use any rule that is allowed inside acl: sections (like user, server, resource, user_glob, etc.) and one additional rule that is allowed only inside access_rules: section, acl: NameOfACL that will look for definition of NameOfAcl inside acl: section and use it for matching. If you have only one ACL rule name to use you can use short form - allow: acl_rule, additionally - allow: all or - deny: all can be shorted still to - allow and ‘- deny`.

Shapers can also be specified using new syntax, but they now go into shaper_rules: section and they look like that:

    - 100: admin
    - 10: all

Rules defined in access: section will use old syntax, and work as before, so you don’t need to update your old config, to adapt it to that change.

At last, one can define module specific access rules directly in modules configuration section, this is simpler to understand when reading configuration.

Let’s get a simple example of the changes. With previous ACL implementation, one could have this:

      - "XXX.XXX.XXX.XXX/32"
      - "aleksey": "localhost"
    admin: allow
    local: allow
    all: allow
    bad_servers: deny
    all: allow
    admin: none
    all: normal
    access: muc
    access_create: muc_create
    access_persistent: muc_create
    access_admin: muc_admin

Which can be translated to this since ejabberd 16.06 with new ACL implementation:

    user: "aleksey@localhost"
    - deny:
      - ip: "XXX.XXX.XXX.XXX/32"
    - allow
    - none: admin
    - normal
      - allow
      - allow: local
      - allow: local
      - allow: admin

Shorter and clearer. Please also note that you can use the JID literally as a string. The previous awkward username: domain syntax can go away.


This is a selection of the most relevant changes:


  • New ACL infrastructure
  • Add shorter version of some common access rules definitions
  • Allow @ inside acl rules user, user_glob or user_regexp to pass both user and server
    in single string
  • Add acl rule access_rules_validator and shaper_rules_validator for use in mod_opt_type and opt_type callback functions.
  • Allow using shapers defined by name like in s2s_shaper: fast
  • Allow mod_opt_type and opt_type to transform values passed to it, and support
    better error reporting
  • Do not call transform_terms multiple times in configuration processing when merging them
  • Don’t halt program when include_config_file is missing/can’t be read
  • Allow again multiple fqdn values in configuration


  • Allow passing username and ip to ejabberd_commands, and use it in mod_http_api
  • Fix path to epmd in ejabberdctl
  • push_roster: must convert read strings to binaries
  • set_presence: Fix command API
  • Fix for modules_update_specs command
  • Add ejabberdctl commands to manage oauth tokens.


  • Bounce messages sent to server JID
  • Fix C2S session leak in rare cases
  • Fix handling of queued stanzas on session timeout
  • Give more time to stop and kill epmd
  • When stopping ejabberd, stop modules after broadcasting c2s shutdown
  • XEP-0198: Use different error message for bounces
  • XEP-0198: Add ‘h’ attribute to element
  • XEP-0198: Also count stanzas when socket is closed


  • Fix pgsql compatibility on delete_old_messages command
  • Handle Redis connection in a separate module
  • Report in SQL when scram is enabled but the stored password isn’t
  • Update SQL escaping
  • Use MEDIUMTEXT type for muc_room.opts in MySQL schema


  • Send unique stanza id and archived tag also in the message carbons
  • Fix “assume_mam_usage: if_enabled”
  • Fix typo in mod_mam:select()
  • Updated support of XEP-0313 from version 0.4 to 0.5.1
  • Mnesia: Avoid cleanup on bag when disc_only, switch in memory
  • Mnesia: Don’t exceed table size limit
  • Mnesia: Use transactions when writing

Client State Indication

  • Fix handling of chat states
  • Simplify check for carbon-copied chat states
  • Simplify handling of PEP stanzas
  • Pass chat states of other resources
  • Unwrap carbon copies when checking for chat states
  • Add queue_pep option
  • Queue chat state notifications
  • Move CSI queue handling code from ejabberd_c2s
  • When stopping, delete only the configured hooks

Other modules

  • ext_mod: Set HTTP/1.0 so Github accepts the request
  • gen_mod: Compile early to remove undefined behaviour warning
  • mod_http_upload: Let client retry HTTP upload on file size mismatch
  • mod_last: Produce mod_last entry on account creation
  • mod_muc_room: Notify on affiliation changes
  • mod_register: Check password with jid:resourceprep when registering account
  • mod_roster: respect roster item changes introduced with roster_process_item hooks upon pushing
  • PubSub: Fix PubSub RSM on get_items
  • PubSub: Add support for PubSub publishing options
  • PEP: Fix sender in case of explicit pep subscriptions
  • ejabberd_xmlrpc: Report error when conversion of argument type fails


As usual, the release is tagged in the Git source code repository on Github.

The source package and binary installers are available at ProcessOne.

If you suspect that you’ve found a bug, please search or fill a bug report on Github.

Let us know what you think 💬

One thought on “ejabberd 16.06

  1. after updating to 160.06 (from 16.04) getting this errors:

    2016-07-11 10:50:07.985 [error] @ejabberd_sql:outer_transaction:468 SQL transaction restarts exceeded
    ** Restarts: 10
    ** Last abort reason: {undef,[{ejabberd_odbc,sql_query_t,[{sql_query,<>,#Fun,#Fun,#Fun,{sql_queries,396}}],[]},{sql_queries,’-roster_subscribe/1-fun-9-‘,8,[{file,”src/sql_queries.erl”},{line,392}]},{ejabberd_sql,sql_query_internal,1,[{file,”src/ejabberd_sq

    ** Stacktrace: [{ejabberd_sql,sql_query_t,1,[{file,”src/ejabberd_sql.erl”},{line,182}]},{sql_queries,update_roster,5,[{file,”src/sql_queries.erl”},{line,359}]},{mod_roster,’-p
    ** When State == {state,,mysql,undefined,30000,<>,1000,{0,{[],[]}}}
    2016-07-11 10:50:07.986 [debug] @ejabberd_sql:sql_query_internal:557 SQL: “rollback;”
    2016-07-11 10:50:07.986 [debug] @mod_roster:process_item_set:408 ROSTER: roster item set error: {aborted,{undef,[{ejabberd_odbc,sql_query_t,[{sql_query,<

    Any help?
    (error appears when doing rename in roster).
    Rechecked twice for mysql database structure changes.
    (Also updated config to use “sql” instead odbs)

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.