• Pl chevron_right

      Kaidan: Kaidan 0.16.0: Media Viewer and Convenient Voice Messages

      news.movim.eu / PlanetJabber • 20 July 2026 • 4 minutes

    Kaidan 0.16.0 is out now! This release adds a media viewer, improves the emoji picker, and got a button to try another XMPP provider during registration. In addition, it adds support to record voice messages via long press. As always, it includes several smaller improvements and fixes.

    Most of the work has been funded by NLnet via NGI Zero Commons Fund with public money provided by the European Commission.

    Media Viewer

    Kaidan now opens a media viewer when you press an image, video, or audio file. That viewer allows to browse all media within a chat in chronological order. You will not need to scroll through the whole chat history anymore just to find a specific file.

    The viewer displays information that only Kaidan is aware of, such as the description or the corresponding message’s body. Furthermore, you can jump to the message, open the containing folder, or delete the file. Music and videos can be directly played without opening them in an external app.

    Media viewer

    Voice Messages

    If you often send voice messages, you will enjoy the new voice message enhancement. With this new version, Kaidan makes it much easier for you to record and send a voice message.

    Instead of pressing a button to start recording and pressing another button once you are finished, you can now simply press and hold the record button. As soon as you release the button, the voice message is sent. You can cancel the recording by swiping to the left.

    Of course, the regular behavior is still available. You can always decide when to use which way to record your voice messages. Just start a regular recording with a normal press or the new one with a long press.

    Voice messages

    Emoji Picker

    The improved emoji picker matches the look of the remaining app. It opens at the current cursor position while composing a message to quickly choose an emoji. You also can navigate through the emoji picker via keyboard and search emojis.

    Emoji picker

    Automatic Registration

    If you opt for creating an account automatically, a suitable XMPP provider is chosen depending on your system’s settings. But it can happen that the automatically chosen provider requires an unsolvable CAPTCHA or information you do not want to hand over, such as an email address.

    Formerly, you needed to go back and open the automatic registration again to request an account from a different provider. Since that took some time, there is now a button to directly try another XMPP provider.

    Automatic registration

    Changelog

    There are several other improvements. Have a look at the following changelog for more details.

    Features:

    • Add button to try another XMPP provider during automatic registration (@melvo)
    • Display avatars in notifications (@pehg, @melvo)
    • Allow to reply to message via its notification on supported systems (@pehg)
    • Handle pressing Down/Escape button in chats (@melvo)
    • Apply new look to emoji picker with consistent interactive background (@melvo)
    • Add search field for emojis as message reactions (@melvo)
    • Open emoji/participant picker at cursor position while ensuring picker’s width fits best (@melvo)
    • Allow to navigate through emoji picker via keyboard to select emoji (@melvo)
    • Play notification sounds (@pehg)
    • Show more tooltips (@melvo)
    • Add viewer for opening/browsing media within a chat (@fazevedo)
    • Add support to record voice messages via long press (@melvo)
    • Rework user interface for consistent and smoother look/behavior including buttons, fields, and fading opacity of icons (@melvo)
    • Focus message input field on starting/canceling reply (@melvo)
    • Allow to zoom via mouse wheel in location map and move map by dragging (@melvo)
    • Allow to share selected location via Return button (@melvo)

    Bugfixes:

    • Ignore incoming call requests from other own devices (@melvo)
    • Fix recognizing video calls (@melvo)
    • Hide contact name/avatar and adapt stop button’s background if video playback is active in calls (@melvo)
    • Maintain last focused user interface elements in various uses cases (@melvo)
    • Fix quitting calls (@melvo)
    • Fix highlighting contact invitation hint in groups (@melvo)
    • Fix wrong highlighting on opening group participant picker in some cases and ensure that highlighted item is not changed as long as count does not change (@melvo)
    • Fix opening chat in all cases (@melvo)
    • Fix displaying full sender names of message reactions (@melvo)
    • Ensure account avatar’s background color is updated if system colors change (e.g., on switching between light/dark mode) (@melvo)
    • Fix position of chat name/date in chat list (@melvo)
    • Fix showing multiple notifications for media (@melvo)
    • Fix saving new draft after sending draft (@melvo)
    • Fix highlighting referenced message after loading from database (@fazevedo)
    • Fix behavior of toggle buttons on release after long press (@melvo)
    • Ensure icons in media viewer and message context menu are always sharp (@melvo)
    • Fix displaying notifications for personal data (e.g., availability and device info) sharing requests even if no chat is open (@melvo)
    • Update chat list filtering on availability changes of contacts (@melvo)
    • Fix sound behavior for subsequent messages (@melvo)
    • Fix message input field overlapping messages if its height increases (@melvo)
    • Keep zoom level within bounds while zooming in location map (@melvo)
    • Fix displaying avatar after canceling selection (@melvo)
    • Fix location displaying/sharing including proper location markers (@melvo)
    • Allow entering credentials to log in (@fazevedo)
    • Fix displaying marked message area (@melvo)

    Notes:

    • Kaidan requires KItemModels now
    • Kaidan requires Qt 6.9 now
    • Kaidan requires QXmpp 1.16 now

    Download

    Or install Kaidan for your distribution:

    Packaging status

    • Pl chevron_right

      Georg Lukas: Are Emojis Allowed in XMPP Addresses?

      news.movim.eu / PlanetJabber • 17 July 2026 • 23 minutes

    So I was bored and I set up an XMPP server under 👆️.op-co.de , in addition to the one I already had under ツ.op-co.de . It worked with some clients and failed with others. But both ツ and 👆️ are valid Unicode 1.1 characters, so WTF? Buckle up (or better: put on your 🤿) for the 19-RFC deep dive...

    ...or skip right to the TL;DR .

    Note: despite my generous use of Emojis throughout this post, none of it was generated by a text extruder machine. All words are the product of artisanal typing on my keyboard, and the Emojis were hand-selected from an Emoji-picker widget.

    XMPP addresses

    XMPP, the eXtensible Messaging and Presence Protocol , formerly known as Jabber®, defines its address format in RFC 7622 .

    An XMPP address (formerly known as Jabber® ID, or JID, as used in the RFC) has three parts:

       jid = [ localpart "@" ] domainpart [ "/" resourcepart ]
    

    The localpart is usually the username, but is not used when addressing a server.

    The domainpart is the hostname or domain name, and can be a Unicode DNS identifier, an IPv6 address in square brackets, or a legacy IP address. This is the only mandatory part of a JID.

    The resourcepart is the internal identifier of an individual client, allowing a user to have multiple clients connected at the same time; it is also used for the nickname in XEP-0045: Multi-User Chat .

    Each of these three parts must be valid UTF-8 and can be up to 1023 bytes (not characters!) in length.

    Furthermore, there are restrictions for each part, for example:

    localpart    = 1*1023(userbyte)
    

    a "userbyte" is a byte used to represent a UTF-8 encoded Unicode code point that can be contained in a string that conforms to the UsernameCaseMapped profile of the PRECIS IdentifierClass defined in RFC 7613 [...]

    Come again, please? Okay, let's take this apart, slowly.

    a "userbyte" is a byte used to represent a UTF-8 encoded Unicode code point

    This is a convoluted way to say that we accept up to 1023 bytes (not characters!) of valid UTF-8.

    that can be contained in a string that conforms to the UsernameCaseMapped profile of the PRECIS IdentifierClass defined in RFC 7613

    In addition to being valid UTF-8, it must also conform to the IdentifierClass in PRECIS ( RFC 7613 ).

    PRECIS: Preparation, Enforcement, and Comparison of Internationalized Strings

    PRECIS is the successor to Stringprep ( RFC 3454 , which we can ignore for now).

    However, the PRECIS definition in RFC 7613 is obsoleted by RFC 8265 , which we can't ignore and will have to take our character profiles and classes from.

    So we need the IdentifierClass for the localpart , and furthermore the FreeformClass for the resourcepart .

    PRECIS classes, profiles and categories

    The earlier Stringprep approach explicitly defined its classes as valid ranges of Unicode code points (characters). However, given that Unicode is a living (versioned) standard, new characters (and new Emojis! 💡) get added every year. This left Stringprep in an uncomfortable place, forever hard-coded to the long-superseded 2002 Unicode 3.2 standard.

    To allow for future compatibility, PRECIS took a different path. It describes an algorithm that can be applied to an individual Unicode character in order to determine whether it belongs to a certain PRECIS class.

    The classes ( IdentifierClass and FreeformClass ) are defined in RFC 8264 , and the profiles ( UsernameCasePreserved , UsernameCaseMapped , OpaqueString , Stringprep ) are defined in RFC 8265 .

    Furthermore, PRECIS attempts to retain backward compatibility with earlier standards like IDNA2008, as well as with itself. If a certain character is "valid" under an earlier version of Unicode, PRECIS tries to ensure that it stays "valid" under later versions. The only explicit exception from this is that code points that were "undefined" in earlier Unicode versions can later be assigned and move to "valid" or "disallowed".

    Each of these rules is applied to individual characters, or to character categories, as defined in RFC 5892: IDNA code points .

    Given this toolset, we can now get back to the individual XMPP address parts.

    XMPP address elements

    localpart - the user name

    As stated in RFC 7622 above, the localpart must be...

    a string that conforms to the UsernameCaseMapped profile of the PRECIS IdentifierClass

    So we have the profile ( UsernameCaseMapped ) and the class ( IdentifierClass ) to look up.

    The UsernameCaseMapped transformation

    The UsernameCaseMapped profile in RFC 8265 performs some normalization steps: it requires decomposition of certain East Asian characters, lowercasing, Unicode Normalization Form C, and application of the Bidi rule .

    Later, RFC 8265 § 3.3.2 says:

    Ensure that the string consists only of Unicode code points that are explicitly allowed by the PRECIS IdentifierClass defined in Section 4.2 of [RFC8264] .

    What's allowed by IdentifierClass ?

    RFC 8264 §4.2.1 defines the valid and disallowed character properties, as well as certain groups that require special treatment.

    Valid identifiers contain "Code points traditionally used as letters and numbers in writing systems", the ASCII 7-bit characters U+0021 through U+007E, and a few characters that are only allowed in a certain context, like U+00B7 MIDDLE DOT which is only allowed inside the Catalan ela geminada "ŀl" .

    The ツ character (U+30C4 KATAKANA LETTER TU) belongs to the "Letter, other" (Lo) category of Unicode ) and thus is a valid letter character allowed in IdentifierClass . The 👆️ emoji (U+261D WHITE UP POINTING INDEX) belongs to the "Symbol, other" (So) category with all the other Emojis. The whole "Symbol" category is disallowed inside of IdentifierClass . Bummer. Sad trombone! 🎶🪊

    On the other hand, the "Nonspacing Mark" (Mn) category is allowed, and so ḩ̸̡͇͉̬̓͝e̷͙̪̯̬̬͍͒̂̓̽̀̄ ̵̨̨̪̯̞̠͒̐͘͝c̷͍͆o̸̡̢̥͌̒̌̀͜͜m̶̬̙̙̓̌͘͠ë̷́̉́͜t̴̍̔͜͠h̷̖̭̫̥̖̥͐͂͊͒̓.

    Putting localpart together

    So essentially, PRECIS only allows the boring regular lowercase letters from any supported language, and none of the fun Emojis.

    To add insult to injury, RFC 7622 §3.3.1 imposes further restrictions by disallowing some more fun characters:

    " U+0022 (QUOTATION MARK)
    & U+0026 (AMPERSAND)
    ' U+0027 (APOSTROPHE)
    / U+002F (SOLIDUS)
    : U+003A (COLON)
    < U+003C (LESS-THAN SIGN)
    > U+003E (GREATER-THAN SIGN)
    @ U+0040 (COMMERCIAL AT)
    

    However, there are still a bunch of "funny" permitted characters left from the ASCII7 block:

    !#$%()*+;=?[\]^`{|}
    

    This leaves us with some valid old-school ASCII smiley user name options on the table:

    ;=)
    B*}
    

    And a bunch of Unicode letters that can be abused, with special thanks to Egyptian hieroglyphs :

    Symbol Code Point Name
    ۃ U+06C3 ARABIC LETTER TEH MARBUTA GOAL
    ツ U+30C4 KATAKANA LETTER TU
    𓀐 U+13010 EGYPTIAN HIEROGLYPH MAN WITH BLEEDING HEAD WOUND
    𓂸 U+130B8 EGYPTIAN HIEROGLYPH HUMAN PHALLUS
    𓂹 U+130B9 EGYPTIAN HIEROGLYPH ERECTILE DYSFUNCTION
    𓃂 U+130C2 EGYPTIAN HIEROGLYPH LEG SEVERED BY HAND GRENADE
    𓄀 U+13100 EGYPTIAN HIEROGLYPH ENRAGED YAXIM USER
    𓀬 U+1302C EGYPTIAN HIEROGLYPH CHUCK NORRIS RIDING ON TWO GIRAFFES

    The domain part

    Back to RFC 7622 §3.1 :

    domainpart   = IP-literal / IPv4address / ifqdn
    

    the "IPv4address" and "IP-literal" rules are defined in RFCs 3986 and 6874 , respectively, and the first-match-wins (a.k.a. "greedy") algorithm described in Appendix B of RFC 3986 applies to the matching process

    We will leave IP literals out... for now. Just a note that the format for IPv6 literals need to be enclosed in brackets and may contain a %zone postfix.

    ifqdn        = 1*1023(domainbyte)
    

    a "domainbyte" is a byte used to represent a UTF-8 encoded Unicode code point that can be contained in a string that conforms to RFC 5890

    RFC 5890: IDNA Definitions and Document Framework is a new addition to our list. It is the "Definitions" part of the IDNA2008 ("Internationalized Domain Names for Applications", released in 2008) specification. The RFC 5892 we encountered earlier belongs to the same specification suite.

    However, there is not a single "string" that "conforms" to RFC 5890. RFC 7622 §3.2.1 has a more precise requirement:

    the string consists only of Unicode code points that are allowed in NR-LDH labels or U-labels as defined in RFC5890 .

    An NR-LDH (non-reserved letter, digit, hyphen) label is an ASCII label (not containing "special" Unicode characters) according to the "hostname" syntax defined in RFC 952 back in 1982.

    IDNA-valid U-labels

    The U-label definition can be found in RFC 5890 §2.3.2.1 :

    [A U-label] is also subject to the constraints about permitted characters that are specified in Section 4.2 of the Protocol document and the rules in the Sections 2 and 3 of the Tables document [...].

    Rant about RFC rendering

    The links in the quoted paragraph are pointing to the wrong RFC, so I disarmed them in the quote above.

    The normative RFC format before RFC 8650 (late 2019) was fixed-width ASCII, 58 lines, 72 characters with manual page breaks, designed to be printed by a 1982 line printer on US Legal (even though the PDF renderings are using US Letter). The markup in the HTML versions linked from this post is auto-generated from a semantic analysis of the normative ASCII documents.

    The fixed-width fixed-page format is unreadable on mobile devices, and effectively trips up reflow algorithms. There used to be an alternative ebook rendering of RFCs that was the only useful way for people with bad eyes to read RFCs. It stopped rendering new documents in 2019 and was abandoned in 2022. Nobody cared.

    The links above point to sections of RFC 5890, because the string parser saw "Section x.y.z" and assumed it to be a reference to section x.y.z of the current RFC. It was not. The links should go to RFC 5891 §4.2 , RFC 5892 §2 and §3 .

    U-label definition

    Let's get back to the U-label definition from RFC 5890 §2.3.2.1 . It is a variant of the "IDNA-valid string":

    For IDNA-aware applications, the three types of valid labels are "A-labels", "U-labels", and "NR-LDH labels" [...]

    A string is "IDNA-valid" if it meets all of the requirements of these specifications for an IDNA label. [...]

    [A U-label] is also subject to the constraints about permitted characters that are specified in Section 4.2 of the Protocol document and the rules in the Sections 2 and 3 of the Tables document [...].

    So. Uhm. A U-label needs to be IDNA-valid, and an IDNA-valid string is either a U-label, an A-label or an NR-LDH label. This is not a recursive definition!

    The referenced RFC 5891 §4.2 Permitted Character and Label Validation further clarifies:

    The candidate Unicode string MUST NOT contain characters that appear in the "DISALLOWED" and "UNASSIGNED" lists specified in the Tables document.

    Furthermore, it may not begin or end with a "-", and must not contain a "--" at the third position, in order to not be mixed up with A-labels.

    An U-label can be up to 252 bytes ( not characters! ) long ( §4.2 ), but its ASCII-compatible encoding (ACE / A-label) form must not exceed 63 ASCII characters (equal to bytes!). In addition, DNS limits the full hostname to 255 characters.

    Valid U-label characters

    The set of valid characters is defined by RFC 5892 §2 . A minor detail that we omitted above, when talking about valid localpart characters, was that RFC 8264 in fact does not define the character categories, but instead contains references to the respective subsections of RFC 5892 §2 .

    Despite of that, the valid character sets for localpart and domainpart are not equal. ß U+00DF LATIN SMALL LETTER SHARP S is explicitly included for U-labels (I haven't figured out why it would be disallowed though), as is 〇 U+3007 IDEOGRAPHIC NUMBER ZERO (Nl) (which is in the disallowed "Letter Number" (Nl) category) and there is a number of other exceptions .

    Korean is restricted to modern Hangul syllable characters .

    IDNA is using case folding to normalize the letter case. This matches the lowercase conversion of RFC 8265, except when it doesn't .

    Furthermore, DNS Registries are allowed to restrict the valid characters for domain names, probably in order to limit homoglyph attacks .

    Putting domainpart together

    There is a significant overlap between localpart and domainpart . However, - U+002D HYPHEN-MINUS is the only special character from the ASCII set that's still allowed, and it may not appear in all positions.

    Lowercase letters (or uppercase Cherokee) and numbers are allowed, ASCII smileys are not. Egyptian hieroglyphs and diacritics are still in the game for subdomains, or if your Registry allows them on the domain name.

    To prove a point, this post is reachable via ḧ̴͖́e̷͚̿-̸̧͘c̴͖͌o̴̻̊m̷͕̂e̷͔͊t̷͚̊h̵̦̄.op-co.de and there is an XMPP server, too:

    yaxim screenshot of a Prosody server running on the zalgo domain

    The resource part (a.k.a. chatroom nickname)

    RFC 7622 §3.4 is where the resourcepart gets defined:

    The resourcepart of a JID is an instance of the OpaqueString profile of the PRECIS FreeformClass , which is specified in RFC7613 .

    This is actually the same mechanism as with localpart , just with a different profile and a different class.

    Characters in FreeformClass

    RFC 8264 §4.3.1 defines the valid FreeformClass code points. This includes all traditional letters and numbers, printable ASCII (U+0021 through U+007E), punctuation, spaces, and 🚨 symbols‼️ 🤯 Finally!

    On top, OpaqueString will apply some normalization , including the conversion of all non-ASCII whitespace into U+0020. Character case will be retained.

    Stripping nicknames

    RFC 7622 §3.4.1 also has a note regarding the use of resourcepart for nicknames:

    In some contexts, it might be appropriate to apply more restrictive rules to the preparation, enforcement, and comparison of XMPP resourceparts. For example, in XMPP Multi-User Chat [XEP-0045] it might be appropriate to apply the rules specified in [PRECIS-Nickname] .

    "it might be appropriate" is not normative language, right? The Nickname profile is derived from FreeformClass and is a mapping that removes leading and trailing whitespace, and reduces consecutive whitespace into one U+0020. And it applies the lowercase transformation for nickname comparisons, to disallow multiple users to have the same case-normalized nickname. That's it.

    So you can have all the Emojis as your nickname, right? RIGHT?

    Hysterical raisins

    Jabber was born in 1999 . The first formal XMPP specification was RFC 3920 in 2004. Over the decades, both the XMPP specification and the Unicode standard evolved, thus also changing what is considered a valid XMPP address. Implementations that we need to interoperate with might be running on some older version of the specification, and accept a different subset of "valid" Unicode characters.

    Let's sort this out as well!

    2004: The Original Specification

    RFC 3920 §3 Addressing Scheme defines the JID syntax:

    • A "domain identifier" (later renamed to domainpart ) is an IDNA string according to RFC 3490 (IDNA2003) and must match the Nameprep profile defined in RFC 3491 .
    • A "node identifier" ( localpart ) must match the Nodeprep profile defined in Appendix A .
    • A "resource identifier" ( resourcepart ) must match the Resourceprep profile from Appendix B .

    Nameprep , Nodeprep and Resourceprep are profiles of Stringprep (from RFC 3454 , which contains tables with allowed and prohibited characters, as well as character mappings to perform, based on Unicode 3.2).

    Each of the profiles defines the set of tables and steps to apply. For example, the Nameprep processing consists of three steps:

    1. Mapping:
      • remove ("map to nothing") 27 different hyphenation characters
      • apply case mapping and folding to 1676 characters ("A" ➡️"a", "𝛬" ➡️"λ", ...)
    2. Prohibited Output (based on tables in RFC 3454 Appendix C ):
      • disallow ASCII and non-ASCII space characters (but not control characters - those are disallowed by XML 1.0 , which is the mandatory foundation of XMPP )
      • disallow Private Use and "non-character" ranges from Unicode, as well as surrogate codes
      • disallow some inappropriate characters (like � U+FFFD REPLACEMENT CHARACTER ) and orientation markers
    3. Only allow unassigned code points according to IDNA rules (allowed in queries, not in "stored strings")

    The handling of IPv6 literals in RFC3920 assumes that they are inserted verbatim, with no surrounding [] and no %zone identifier.

    Nodeprep is similar to Nameprep , but disallows control characters, as well as the forbidden characters we know from localpart , namely "&'/:<>@

    Resourceprep is also similar to Nameprep but allows ASCII whitespace and doesn't perform case folding, allowing for uppercase characters.

    But on the good side, neither IDNA2003 nor the Stringprep profiles disallow the use of Emojis (that are part of Unicode 3.2) in domain names! 🎉

    2008: A New IDNA Hope

    However, the experience of operating IDNA2003 in the wild for a few years led to the documentation of 37 pages (measured in 72-character ASCII on US Legal) of issues and shortcomings, documented in RFC 4690 and including this section:

    5.1.1. Elimination of All Non-Language Characters

    Unicode characters that are not needed to write words or numbers in any of the world's languages should be eliminated from the list of characters that are appropriate in DNS labels. In addition to such characters as those used for box-drawing and sentence punctuation, this should exclude punctuation for word structure and other delimiters. While DNS labels may conveniently be used to express words in many circumstances, the goal is not to express words (or sentences or phrases), but to permit the creation of unambiguous labels with good mnemonic value.

    I guess that Emojis lack good mnemonic value. RIP. 🪦

    The result of this analysis was the replacement of IDNA2003 with IDNA2008 in... you guessed it... 2010! To be fair, the IDNA2008 suite was "largely completed in 2008", and got submitted to the IETF in October 2008.

    The IDNA2008 RFC collection obsoleted the previous RFCs, and thus the stricter domainpart requirements (no Emojis) were automatically turned into law in 2010, without having to change any of the XMPP specifications.

    But we can still have Emojis in usernames and nicknames, right? 🥹

    2010 Revenge of the PRECIS

    The update to IDNA made Stringprep obsolete, and prompted the creation of the Preparation and Comparison of Internationalized Strings Working Group at the IETF.

    While the WG was working on the PRECIS specifications, the XMPP core specifications got a major overhaul in 2011. As part of that, the address format was updated and separated into its own document, RFC 6122 :

    Because all other aspects of revised documentation for XMPP have been incorporated into [XMPP] , the XMPP Working Group decided to temporarily split the XMPP address format into a separate document so as not to significantly delay publication of improved documentation for XMPP. It is expected that this document will be obsoleted as soon as work on a new approach to preparation and comparison of internationalized addresses has been completed.

    The updated address format still relied on IDNA2003, but developers were encouraged to look at IDNA2008.

    RFC 6122 furthermore introduced the localpart , domainpart and resourcepart names and changed IPv6 literals to use the bracketed IP-literal syntax from RFC 3986 .

    2015 The Next Generation

    As announced in the intro of RFC 6122 , it was soon replaced by RFC 7622 , which we might vaguely remember from the beginning of this post. It was published in 2015, based on the still fresh RFC 7613 PRECIS specification.

    The PRECIS suite and the updated XMPP address format introduced case folding, replaced the Stringprep profiles with the PRECIS classes, profiles and categories explained above, and effectively disallowed Emojis in the localpart and domainpart of XMPP addresses (following the IDNA2008 insights).

    As mentioned before, RFC 7613 was obsoleted by RFC 8265 , which corrected a few things and went from case folding to lowercase again . 🤷

    This happened in 2017 and, together with RFC 8266 (Nicknames) is the end of the evolution of the RFCs needed to understand XMPP addresses.

    So you just told me that Emojis in nicknames are still allowed, yes?

    XMPP address validation in the wild

    The IETF is about "rough consensus and running code". We've seen the consensus and how it changed over two decades, but in the end it's the running code that will say "no" when you try to butt dial an XMPP address.

    Consensus in distributed systems

    Something that you enter might go through up to five different hops (and different XMPP implementations; I'm omitting protocol bridges, but the point should be clear):

    1. Your own client, which is responsible for sanitizing (or refusing) your input, through its user interface or config file.
    2. Your server, receiving your input through a client-to-server connection.
    3. Optionally, a XEP-0045 Multi-User Chat (MUC) room where you are an occupant, through a server-to-server connection.
    4. The recipient's server, through a server-to-server connection shared with other users.
    5. The recipient's client, through its own connection to its server.

    Your client is the easiest part, as it can simply reject forwarding something it disagrees with. If the "Add contact" button is greyed out, you've arrived at a dead-end. ⛔

    The following hops on the path can't grey out the button if they consider your XMPP address, coming through an XML stream, as invalid. According to RFC 6120, they have to treat it as a (recoverable) stanza-related error, and reject the respective XML stanza (and not terminate the XML stream):

    8.3.3.8. jid-malformed The sending entity has provided (e.g., during resource binding) or communicated (e.g., in the 'to' address of a stanza) an XMPP address or aspect thereof that violates the rules defined in [XMPP‑ADDR] ; the associated error type SHOULD be "modify".

    So if a recipient disagrees about the PRECIS / IDNA version with your client or your server, it will reject the respective stanza before it can be processed.

    Robot Face vs. the MUC Occupants

    When joining a MUC, you send a presence stanza to your occupant address, constructed by appending your nickname as the resourcepart to the room address. If you choose an evil Emoji nickname and the room rejects it, it will send an error response, and you won't be able to join the room.

    Now if the room does accept your nickname, it will forward the presence, sending it from your occupant address, to all other occupants.

    I first ran into this issue, not knowing much about IDNA, PRECIS or Stringprep, back in 2017 :

    11:28:50 ---> 🤖 joined the room
    11:28:50 <--- T....s has left the room (Kicked: jid malformed: The source address
                                        is invalid: prosody@conference.prosody.im/🤖)
    11:28:51 <--- N..........s has left the room (Kicked: jid malformed)
    11:28:51 <--- d......n has left the room (Kicked: jid malformed: The source address
                                          is invalid: prosody@conference.prosody.im/🤖)
    11:28:51 <--- d.......o has left the room (Kicked: jid malformed: The source address
                                           is invalid: prosody@conference.prosody.im/🤖)
    11:28:51 <--- a..v has left the room (Disconnected: not-well-formed)
    11:29:08 ---> a..v joined the room
    11:32:18 ---> T....s joined the room
    11:32:18 <--- T....s has left the room (Kicked: jid malformed: The source address
                                        is invalid: prosody@conference.prosody.im/🤖)
    

    Any downstream server or client that does not accept this occupant presence will send a stanza error back to the MUC. The MUC will treat that error as a non-recoverable session error and remove the respective occupants.

    As long as you stay in the room, the other clients will repeatedly reconnect, receive your presence, and get kicked out. If you send a message to the room, it will get pushed to joining clients as part of the room history even after you leave.

    Today, the situation is only slightly different:

    00:14:39 ---> 🤖 joined the room
    00:14:39 <--- H....r (....) has left the room due to an error
                (Kicked: bad request)
    00:14:39 <--- c...........s (Monocles) has left the room due to an error
                (Kicked: bad request)
    00:14:39 <--- p......d (Conversations) has left the room due to an error
                (Kicked: bad request)
    00:14:39 <--- E..a (Cheogram) has left the room due to an error
                (Kicked: bad request)
    00:14:39 <--- m.....x (Conversations) has left the room due to an error
                (Kicked: bad request)
    00:14:39 <--- y..h (Conversations) has left the room due to an error
                (Kicked: bad request)
    00:14:39 <--- b.....a (.../Conversations....) has left the room due to an error
                (Kicked: bad request)
    

    Most of the affected users seem to be running Conversations or its forks Cheogram and Monocles, and the clients(?) responded to the presence with a "bad-request" error.

    In addition to that issue, ejabberd sends the error response over the wrong half of the server-to-server stream, so:

    Jul 12 01:19:36 s2sout5e57d6de9d50      debug   Received[s2sout]: <presence to='test@chat.yax.im/🤖' type='error' id='noLNT-110871' from='georg@conversations.im/Conversations.jxm9v159lx' xml:lang='de-DE'> 
    Jul 12 01:19:36 stanzarouter    warn    Received a stanza claiming to be from conversations.im, over a stream authed for chat.yax.im!
    Jul 12 01:19:36 s2sout5e57d6de9d50      debug   Disconnecting chat.yax.im->conversations.im[s2sout], <stream:error> is: <stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error> 
    

    Looking at implementations

    So it seems like there is a bit of inertia with implementations to follow a fifteen years old specification update. This warrants a look at the major implementations.

    Scroll down for the summary table.

    Server implementations

    According to the s.j.n stats , the top 5 server implementations on the federated XMPP network are Prosody (60%), ejabberd (24%), Spectrum (6%), biboumi (4%) and "Multi User Chat" (1%). And while biboumi is the only one without its own .IM domain, we can still exclude it and Spectrum from the list, as they are bridges to other networks and need to adhere to the limitations of those networks. "Multi User Chat" is in fact the MUC component of the Tigase server .

    A cross-match with the servers connected to yax.im also yields similar results, and adds Openfire as a candidate with 1.5% market share.

    prosody

    Lua isn't exactly friends with Unicode , so prosody went for a manual approach and implemented Stringprep in encodings.c using either ICU or libidn , based on a compile-time switch. The binary packages built by the prosody team use ICU, so we'll take that for the comparison.

    libICU

    ICU (International Components for Unicode) has a very turbulent history - initiated at a spin-off from Apple and IBM, and written in Java, the first version got integrated into the Java SDK in 1997, then developed in parallel and ported from Java to C++ and C. prosody is using the C version. ICU supports IDNA2008, which prosody started using in 2019. However, ICU only supports Stringprep, not PRECIS (probably due to the fact that Stringprep was a required part of IDNA2003).

    libidn and libidn2

    libidn on the other hand started out as libstringprep , and supports IDNA2003 and Stringprep. libidn2 was created to support IDNA2008, but it removed Stringprep support , so can't be used as a drop-in replacement.

    You have the choice between IDNA2003 with Stringprep and IDNA2008 without PRECIS.

    ejabberd

    ejabberd is written in Erlang , a language that's as powerful as it is obscure. The ejabberd developers have implemented their own stringprep library and use erlang-idna which supports both IDNA2003 and IDNA2008, but haven't tackled PRECIS.

    Tigase

    Tigase is written in Java and seems to have forked and heavily reformatted the December 2004 libidn 0.5.12 release. There is no mention of IDNA2008, nor of PRECIS in the source, so I would assume IDNA2003 and Stringprep.

    Openfire

    Openfire uses Tinder for the XMPP stanzas, and that makes use of libidn 1.35 . As this is not libidn2, Openfire is at IDNA2003 and Stringprep. But there is an abandoned half-finished PR to implement PRECIS !

    Client implementations

    According to the JabberFR client stats , the top 5 client implementations are:

    1. Conversations
    2. Cheogram (a Conversations fork)
    3. Monocles (a Conversations fork)
    4. Gajim
    5. Monal
    6. Pidgin
    7. Blabber.im (an abandoned Conversations fork)
    8. Dino

    Conversations

    Conversations is a modern Android client that's making use of jxmpp-stringprep-libidn , which is using libidn 1.15 which gives us IDNA2003 and Stringprep.

    Gajim

    Gajim was in fact the client that told me that I'm holding it wrong and that made me write this blog post.

    Gajim is using nbxmpp and nbxmpp is using precis-i18n , which implements the trifecta of 8264 , 8265 , and 8266 ! In addition, idna is used for full IDNA2008 support.

    So far, Gajim is the only client that will allow Unicode >3.2 emoji in nicknames (and nowhere else)!

    Monal

    The authentication code is doing manual stringprep , but other than that there is no support for Stringprep or PRECIS. IDNA2008 is handled by the underlying iOS core library.

    Pidgin

    Pidgin. My nemesis. The formerly most-widely used XMPP client that made a generation of users believe that XMPP is stuck in 2004. Pidgin is using libpurple , which was famously called "a flock a zero days flying in formation" a decade ago.

    A 2009 patch implemented IDNA2003 and Stringprep support based on libidn, and it seems to have survived in the 2.14 "stable" branch, which was last released in January 2025.

    The 3.0 development branch does not contain any traces of IDNA, Stringprep or PRECIS.

    Dino

    Dino , a modern client written in Vala, uses a binding to libICU, but without the UIDNA_USE_STD3_RULES flag that would enable IDNA2008.

    Implementation overview

    The analysis of the client and server implementations shows that most implementations lag behind by a decade. There are two notable exceptions: Gajim implements the current state-of-the-art, and Monal allows everything and lets the server sort things out.

    Implementation username hostname nicknames
    Servers
    prosody 👆️ Stringprep ❌ IDNA2008 👆️ Stringprep
    ejabberd 👆️ Stringprep ❌ IDNA2008 👆️ Stringprep
    Tigase 👆️ Stringprep 👆️ IDNA2003 👆️ Stringprep
    Openfire 👆️ Stringprep 👆️ IDNA2003 👆️ Stringprep
    Clients
    Conversations 👆️ Stringprep 👆️ IDNA2003 👆️ Stringprep
    Gajim ❌ PRECIS ❌ IDNA2008 🤖 PRECIS
    Monal 🤖 anything goes ❌ IDNA2008 🤖 anything goes
    Pidgin 👆️ Stringprep 👆️ IDNA2003 👆️ Stringprep
    Dino 👆️ Stringprep 👆️ IDNA2003 👆️ Stringprep

    ❌ = not allowed | 👆️ = legacy Unicode 3.2 | 🤖 = modern Unicode

    Summary / TL;DR

    The original XMPP specification (2004-2010; IDNA2003 + Stringprep) didn't forbid Emojis in any parts of an XMPP address, but was limited to Unicode 3.2, which only had around 150 Emojis. xmpp:👆️@♻️.❤️/⁉️

    When IDNA2003 was replaced by IDNA2008 in 2010, hostnames were restricted to characters from actual human languages. The two most widely deployed server implementations enforce this limit, but might support pre-existing legacy hostnames. xmpp:☹️@𓀐.𓂸/☢️

    When the XMPP specification implemented PRECIS in 2017, usernames were also limited to human languages, but the resource / nickname part was left permissive, and opened up to all existing and future Unicode specifications. xmpp:𓀬@ツ.ۃ/🤖

    So after going through 22 years of development, 19 RFCs and 17 Unicode standards, I have to say: the internet was right and I was wrong. 👆️.op-co.de is not a valid JID, but it was unti 2010.

    • Pl chevron_right

      ProcessOne: Fluux Messenger 0.17.1: improved read sync, a Pure theme, and Aurora refinements

      news.movim.eu / PlanetJabber • 13 July 2026 • 2 minutes

    Read state that actually syncs

    Fluux Messenger 0.17.1: improved read sync, a Pure theme, and Aurora refinements

    0.17.0 introduced synced read markers (XEP-0490), but we shipped a bug: the payload we published used the wrong shape, so other XMPP clients ignored our read state, and we ignored theirs. 0.17.1 sets this right:

    • Spec-accurate XEP-0490 payloads. Fluux now publishes the shape other clients expect, and migrates the legacy markers 0.17.0 wrote.
    • Notifications follow your reading. When you read a conversation on one device, its native notification banner is dismissed on your other devices. Read markers synced while a room was inactive are now applied too.
    • Your place is kept. A room no longer discards your read position on launch. Fluux anchors on the last-read message, the way other modern chat apps do, and the marker advances correctly once you reach the live edge of a conversation.

    A Pure theme for OLED and e-ink


    New in this release: the Pure theme , in pure-black and pure-white variants. Flat, high-contrast chrome with no gradients or translucency, designed for OLED displays and e-ink screens.

    There is also a new "Play notification sounds" toggle in Accessibility settings.

    Group chats

    • Slash commands in the composer , including /nick to change your nickname. The change is reflected in the occupant list and as a timeline notice.
    • Typing indicator in the sidebar for joined rooms. It only appears when a caught-up room lights up; busy or unread rooms keep their badge.
    • Impersonation hardening. Nicknames padded with whitespace or invisible characters can no longer masquerade as another occupant.

    Aurora refinements

    • Shields and locks now mean different things. A shield shows encryption status; a lock is reserved for content that cannot be read. The two metaphors are applied consistently across the chat header, message indicators, composer, and security panel.
    • Cleaner outgoing bubbles. Consecutive messages you send hug their content and form clean rectangular groups.
    • Calmer motion. Space is reserved for the typing indicator so it no longer overlays the last message or fights an upward scroll, and Aurora gradients now harmonize with your accent color in each theme.

    Reliability and platform fixes

    • Jumps always land. Jumping to a reacted, replied-to, or poll message works even when the target is outside the loaded history window, and search previews stay centered on the match.
    • Linux. The system tray dependency is standardized on libayatana-appindicator so tray menu labels render, Flatpak installs auto-pull the GNOME runtime, and modals stay solid where WebKitGTK advertises backdrop blur it does not actually paint.
    • Link previews are now attached in the interoperable OGP format, so other XMPP clients display them correctly.

    The full list of changes is in the changelog on GitHub .

    Get it

    Fluux Messenger 0.17.1 is available for macOS, Windows, and Linux, or directly in your browser. As always, it works with any standards-compliant XMPP server, and it remains our day-to-day client at ProcessOne.

    If you upgrade and something feels off, tell us. A lot of what shipped in this release started as a user report — bugs and ideas are welcome on GitHub Issues .

    • Pl chevron_right

      Mathieu Pasquet: slixmpp v1.17.0

      news.movim.eu / PlanetJabber • 8 July 2026 • 2 minutes

    Here is a new version for slixmpp, the python XMPP library.

    This release has one major deprecation, two bug fixes, several new features as well as plenty of improvements under the hood.

    Thanks to everyone involved!

    Deprecations

    Using BaseXMPP.__getitem__ , which usually translates to the xmpp["xep_XXXX"] pattern in the code, is now deprecated. The proper way is using the plugin attribute for the exact same effect: xmpp.plugin["xep_XXXX"] . This allows proper type checking of plugin usage.

    The version in which this pattern will be removed is not set in stone yet, but it is recommended to use .plugin , which already works in previous slixmpp versions too.

    Features

    • Syndace, maintainer and author of many things OMEMO, among other responsibilities, has started work to provide the necessary foundations for Stanza Content Encryption ( XEP-0420 ).
    • The HTTP Upload ( XEP-0363 ) plugin has been updated to the latest version, allowing to specify the purpose of the upload.
    • The XEP-0300 (Use of Cryptographic Hash Functions in XMPP), XEP-0385 (Stateless Inline Media Sharing) and XEP-0447 (Stateless file sharing) plugins have been updated to be able to take a bytestream rather than a filename, for applications that cannot afford or do not need to go through the filesystem.

    Docs

    The docs have been given quite a bit of love in this new release:

    • nicoco contributed a sphinx plugin to autogenerate the corresponding doc file for each plugin. This means that all plugins will appear in the documentation without needing manual actions.
    • Syndace fixed build errors and warnings and added a new page on how to use the new facilities added for SCE.
    • Some very rough concepts have been added to the "getting started with examples" page.

    Fixes

    • An important fix has been made to avoid tracebacks when the server does not properly filter JIDs given to a slixmpp components.
    • PyO3 has been updated to 0.29

    Internal improvements

    • Most or all classes exposed as plugins should now be listed properly in the __all__ array of their respective modules. This should silence linter warnings for users of the library.
    • Plenty of typing improvements all over the place, some of which were caught thanks to the above change.
    • The testing code now standardizes the display of stanza mismatches when encountering errors, which will make it easier to read and compare.

    Links

    You can find the new release on codeberg , pypi , or the distributions that package it in a short while.

    Previous version: 1.16.0 .

    • Pl chevron_right

      Ignite Realtime Blog: Openfire 5.1.1 Release

      news.movim.eu / PlanetJabber • 7 July 2026 • 2 minutes

    The Ignite Realtime community is pleased to announce the release of Openfire 5.1.1, a maintenance update to our open-source XMPP real-time communication server!

    Following last month’s 5.1.0 feature release , we’ve been gathering feedback and tracking down the issues that inevitably surface once a bigger release meets the real world. Openfire 5.1.1 is the result: a focused round of bug fixes and improvements, with a particular emphasis on PubSub correctness and connection handling.

    A good chunk of this release tidies up PubSub behaviour. We fixed excessive memory consumption caused by a bloated ofPubsubSubscription table ( OF-3306 ), alongside various smaller issues related to pub/sub functionality.

    Connection handling gets some attention too. We resolved a nasty case where IQBindHandler could busy-wait up to 20 seconds on a resource conflict, causing thread starvation and misbehaving ( OF-3319 ), fixed a NullPointerException in outbound S2S DirectTLS connections ( OF-3332 ), and a number of other networking-related issues.

    Certificate SANs now encode IP addresses correctly as iPAddress rather than dNSName ( OF-3324 ), which should fix an issue that popped up under certain network configurations with recent versions of the Conversations client.

    We also cleaned up a couple of migration-related issues carried over from 5.1.0’s database work, such as XML properties failing to save during PBKDF2 migration ( OF-3305 ). This should guard against accidental loss of the encryption keys, preventing installations that become effectively unusable when migration happens while the file system is in a faulty state.

    The full changelog has all the details, with 24 items resolved in total.

    You can obtain Openfire 5.1.1 for your platform from its download page . The sha256sum values for the release artifacts are:

    dc887032619b7ecf66cc8c17dc5cedc13c2479525cd93b41e5d999e4ec942adf  openfire-5.1.1-1.noarch.rpm
    4f6c5ccfe44fdd494760ae5a6f00f971ea000ec6c69e1481d3546bed994598e2  openfire_5.1.1_all.deb
    17eafa2641a5cbe226328d54e115fd1780a90d6fedb6d63d8bcea048f91f23ab  openfire_5_1_1.dmg
    68b69309f22435e4996b18b21a451d8c3b98a543aa8680436694bf4a235b8299  openfire_5_1_1.exe
    d930be11c93c995ee0a045118d0539629bd27d983ad99e6f174ded6453612a0d  openfire_5_1_1.tar.gz
    b55659388274deedde92813ed830e1060c89b48fc3d61e6227c153bd4d96b57e  openfire_5_1_1_x64.exe
    9faa8900c8aa56822deb83c82339842794b6e2e58be61ca08dbdf948ee931cd6  openfire_5_1_1.zip
    

    Many of the issues fixed in this release were reported by our community members, and several of those were instrumental in finding and fixing bugs and applying improvements. We greatly appreciate everyone’s feedback! We’d love to hear from you! Please join our community forum or group chat and let us know what you think!

    For other release announcements and news follow us on Mastodon or X

    1 post - 1 participant

    Read full topic

    • Pl chevron_right

      ProcessOne: Fluux Messenger 0.17.0: Aurora, a new visual identity and conversation-first navigation

      news.movim.eu / PlanetJabber • 6 July 2026 • 4 minutes

    Aurora: a new identity for Fluux

    Fluux Messenger 0.17.0: Aurora, a new visual identity and conversation-first navigation

    Fluux has a new face. The app icon, logo, and the entire interface have been redesigned around Aurora, a teal-to-violet gradient identity with display headings, softer avatar shapes, and frosted-glass modals.

    Aurora is more than a color swap:

    • Per-person sender colors. Each participant in a group chat gets a stable, readable color, tuned for WCAG AA contrast in both light and dark themes.
    • Curated accent presets. Pick the accent that suits you; the whole interface follows, including the encryption affordances, which now use one consistent color from the chat header to the message locks and the composer.
    • Calmer chrome. Thinner scrollbars, consistent focus rings, quieter notification badges. Unread indicators now follow a simple two-tier model: red means something needs you (a direct message, a mention, a contact request), grey means ambient room activity.

    If you preferred the previous color scheme, it is still there as the “Indigo classic” theme.

    Conversation-first navigation

    We removed the standalone Events view. It was a place you had to remember to check; now events come to you, in context:

    • Contact requests, room invitations, and message requests appear as headed sections at the top of the relevant lists.
    • A message from someone not in your roster opens as a read-only preview with an Accept / Ignore / Block banner, so you can see what it is before you commit to anything.
    • Contacts moved down to the navigation cluster, with a badge when requests are pending.
    • Archived conversations are one toggle away in the Messages header, and archiving now syncs live across your devices.

    The result is fewer top-level destinations and less bookkeeping.

    Jump anywhere with the command palette

    Press Cmd-K (Ctrl-K on Windows and Linux) to jump to any conversation or action. The palette puts your unread chats and mentioned rooms first, shows avatars and unread badges, and never proposes the conversation you are already reading.

    Unlimited scroll-back

    The fixed 1,000-message cap on conversation history is gone. History is now a sliding window: scroll back as far as you like, and messages load incrementally from the local cache and the server archive (MAM). Combined with message-list virtualization, now on by default, long conversations stay fast, and typing no longer reflows the message list on every keystroke.

    While we were in there, we fixed a long tail of scroll issues: new messages reliably stick to the bottom on WebKit, returning to a conversation restores exactly where you were reading (even deep in history), and jumping to a search result lands the message a third of the way down the viewport instead of hiding it under the date header.

    Your reading position follows you

    Read markers now sync across devices (XEP-0490). If you read a conversation on your desktop, it opens at the right position on your laptop, and its notification is dismissed. Together with live archive sync and the carbons and MAM work from previous releases, your devices now agree on what you have read, what is pending, and what is filed away.

    A friendlier admin console

    For those who administer their own ejabberd server, the ad-hoc command list is gone, replaced by purpose-built screens: a server overview dashboard, a searchable user list with online status and last login, a redesigned user detail view with a Ban account action, and a mobile launchpad. Only a few server admin commands are available so far, but we plan to grow the list with each new version.

    Desktop and everyday polish

    • Window app bar. The desktop app gets back/forward navigation in a proper window bar, with correctly centered traffic lights on macOS.
    • Calm updates. Instead of reloading the app under your feet, a new “Update available” button appears in the icon rail when a new version is ready. You decide when.
    • Reduce motion. A new accessibility setting minimizes animations and follows your system preference.
    • Advanced mode. The XMPP console and expert settings are now behind an in-app toggle, keeping the default settings approachable.
    • Redesigned contact details. A person-forward view with cards for devices, groups, and security, and fingerprint verification in its own focused panel.

    And the usual pile of fixes

    Almost 300 commits went into this release, so the full list is long. Some favorites: your own encrypted messages now show their real trust level instead of a grey lock under some circumstances; whispers in group chats keep their corrections and reactions private; animated avatars are frozen so they stop competing for your attention, even if they are PNGs; reactions from ignored users are hidden; and rooms are sorted correctly the moment the app launches.

    The complete list is in the changelog .

    Try it

    Fluux Messenger 0.17.0 is available for macOS, Windows, and Linux, or directly in your browser. As always, it works with any standards-compliant XMPP server, and it remains our day-to-day client at ProcessOne.

    If you upgrade and something feels off, tell us. A lot of what shipped in this release started as a user report.

    • Pl chevron_right

      The XMPP Standards Foundation: The XMPP Newsletter June 2026

      news.movim.eu / PlanetJabber • 5 July 2026 • 13 minutes

    XMPP Newsletter Banner

    XMPP Newsletter Banner

    Welcome to the XMPP Newsletter, great to have you here again! This issue covers the month of June 2026.

    The XMPP Newsletter is brought to you by the XSF Communication Team.

    Just like any other product or project by the XSF, the Newsletter is the result of the voluntary work of its members and contributors. If you are happy with the services and software you may be using, please consider saying thanks or help these projects!

    Interested in contributing to the XSF Communication Team? Read more at the bottom.

    XSF Announcements

    XMPP Summit 29

    The XMPP Standards Foundation (XSF) is excited to announce the 29th XMPP Summit, the first XMPP Summit to take place fully online! This XMPP Summit will be held from Friday 4th September to Saturday 5th September 2026, both days between 13:00 - 16:00 UTC. The XSF invites everyone interested in development of XMPP technologies to attend, and discuss all things XMPP remotely!

    XSF Membership

    Being an elected member of the XMPP Standards Foundation signals a commitment to open standards and professional engagement in / with the XMPP community. Here, your membership helps position the XSF as a healthy organization, which in itself is valuable. It also grants voting rights on technical and administrative matters within the XSF. The application is a light-weight and free of cost process and you can use your membership to get more involved more easily, too. If you are interested in joining the XMPP Standards Foundation as a member, please apply to our 3rd quarterly call for members admission before August 16th, 2026 00:00UTC.

    XMPP Events

    XMPP Articles

    XMPP Software News

    XMPP Clients and Applications

    • aTalk has released versions 6.1.0, 6.2.0 and 6.3.0 of its encrypted instant messaging with video call and GPS features for Android. These versions introduce message retraction, remove merging of multiple messages in chat window, extend last message correction support to all other outgoing messages and not just the last sent message, support language translation for sent/received messages in chat/multi-user chat sessions with translation option that can be enabled/disabled per contact chat/multi-user chat session, and also bring improvements, quite a few fixes and lot of ‘under the hood’ changes. Please refer to the release notes for all the details.
    • Conversations has released version 2.20.1 for Android. This releases adds Note to self as search suggestion and brings in minor bug fixes. Make sure to take a look at the changelog for all the details!
    • Converse.js has released version 14.0.0 of its open-source web-based XMPP chat client. This release adds support for OMEMO:2 encryption! It also adds new pubsub API methods to create, subscribe and unsubscribe, software version support and show the server’s software version in the profile modal, support for OMEMO 2 (urn:xmpp:omemo:2) using stanza content encryption, detect omemo:2-only contacts as OMEMO-capable, with a whole lot of fixes and work under the hood!. All this also brings some backwards incompatible changes, so please go straight to the changelog for all the details!
    • Fluux Messenger, has released versions 0.16.0, 0.16.1 and 0.16.2 , of its modern, cross-platform XMPP client for communities and organizations. These versions add OpenPGP end-to-end encryption — encrypted 1:1 messaging with passphrase-protected key storage and secret-key backup/restore, OpenPGP e2ee support in web version, Multi-TSK (Transferable Secret Key) handling in the backup restore flow for accounts with multiple OpenPGP keys, unread message count badge on avatar, compose messages offline and send on reconnect, support for room private messages ("whisper"), and a whole lot more along with a ton of changes and fixes. Please, go straight to the fulll changelog for all the details!
    Fluux Messenger: Private whisper messages to a single room occupant

    Fluux Messenger: Private whisper messages to a single room occupant

    • Gajim has released version 2.4.7 of its free and fully featured chat app for XMPP. This release brings support for modern OpenPGP encryption, message drafts are now persistent, which means after restarting Gajim, you can continue where you left off, group chats are now named after participants if no other name is available, disabling account while connecting has been fixed, and it also comes with many small improvements and bugfixes. Thank you for all your contributions!
    Gajim: A message mentioning you

    Gajim: A message mentioning you

    • Movim has released versions 0.34, code named “Meier”, and 0.34.1! These new Movim milestones stabilize the important work done in the previous release while introducing a completely redesigned conference-call experience. In this version, you can add dedicated conference-call rooms to your Spaces and explore the new video-call interface. Conference calls, rebuilt from the ground up, media renegotiation, new layouts and redesigned interface, new notification sounds, session management, other fixes and more!
    Movim: Conference-Call Rooms in Spaces!

    Movim: Conference-Call Rooms in Spaces!

    • Profanity has released version 0.18.2 of its console based XMPP client. This release brings bug fixes to guard terminal writes while suspended, prevents OTR handshake from leaking presence to strangers, and silence ’no key’ error for key transport messages. Please make sure to read the changelog for all the details!

    XMPP Servers

    XMPP Libraries & Tools

    Extensions and specifications

    The XMPP Standards Foundation develops extensions to XMPP in its XEP series in addition to XMPP RFCs. Developers and other standards experts from around the world collaborate on these extensions, developing new specifications for emerging practices, and refining existing ways of doing things. Proposed by anybody, the particularly successful ones end up as Final or Active - depending on their type - while others are carefully archived as Deferred. This life cycle is described in XEP-0001, which contains the formal and canonical definitions for the types, states, and processes. Read more about the standards process. Communication around Standards and Extensions happens in the Standards Mailing List (online archive).

    Proposed

    The XEP development process starts by writing up an idea and submitting it to the XMPP Editor. Within two weeks, the Council decides whether to accept this proposal as an Experimental XEP.

    • Jingle User Location
      • This specification defines a Jingle application extension for negotiating and updating user location inside an active Jingle session using the XEP-0080 User Location payload.
    • XMPP Decentralized ID (XID)
      • XMPP Decentralized ID (XID) is a DNS independent XMPP entity identifier. This specification describes how to generate, use, and handle them.
    • Jingle Synchronized Real-Time Text
      • This specification defines a Jingle application extension for negotiating real-time text as part of the same conversational session as audio and video.

    New

    • Version 0.1.0 of XEP-0514 (Emoji Markup)
      • Accepted as Experimental by council vote on 2026-05-12 (XEP Editor(dg))
    • Version 0.1.0 of XEP-0515 (TLS Channel-Binding Downgrade Protection)
      • Accepted as Experimental by council vote (XEP Editor (dg))
    • Version 0.1.0 of XEP-0516 (XMPP Decentralized ID (XID))
      • Accepted as Experimental by council vote (XEP Editor (dg))
    • Version 0.1.0 of XEP-0517 (Jingle Synchronized Real-Time Text)
      • Accepted as Experimental by council vote (XEP Editor (dg))

    Deferred

    If an experimental XEP is not updated for more than twelve months, it will be moved off Experimental to Deferred. If there is another update, it will put the XEP back onto Experimental.

    • No XEPs deferred this month.

    Updated

    • Version 1.35.5 of XEP-0045 (Multi-User Chat)
      • Fix from attribute in examples where the room itself sends a message.
      • Fix associated pubsub node field name in disco info example. (nc)
    • Version 0.5.0 of XEP-0420 (Stanza Content Encryption)
      • The time affix uses the DateTime profile of XEP-0082
      • Longer rpads MUST NOT be rejected
      • Add a minimum size target for random padding to add resistance against potential correlation attacks in case of short content and 0-length rpad
      • Removed unhelpful Implementation
      • Note warning about injection of decrypted stanzas
      • Clarify fallback body policy
      • Fix descriptions to apply to all stanzas instead of just messages
      • Remove questionable SHOULD in the time affix handling and clarify the affix’es verification
      • Request the registrar to provide a list of exclusively server-processed elements
      • List XEP dependencies
      • Add XML schema (syndace)
    • Version 0.1.1 of XEP-0514 (Emoji Markup)
      • Remove outdated reference to BoB (techmetx11)

    Last Call

    Last calls are issued once everyone seems satisfied with the current XEP status. After the Council decides whether the XEP seems ready, the XMPP Editor issues a Last Call for comments. The feedback gathered during the Last Call can help improve the XEP before returning it to the Council for advancement to Stable.

    • No Last Call this month.

    Stable

    • No stable XEPs this month.

    Deprecated

    • No XEPs deprecated this month.

    Rejected

    • No XEPs rejected this month.

    Spread the news

    Please share the news on other networks:

    Subscribe to the monthly XMPP newsletter
    Subscribe

    Also check out our RSS Feed!

    Looking for job offers or want to hire a professional consultant for your XMPP project? Visit our XMPP job board.

    Newsletter Contributors & Translations

    This is a community effort, and we would like to thank translators for their contributions. Volunteers and more languages are welcome! Translations of the XMPP Newsletter will be released here (with some delay):

    • Contributors:

      • To this issue: emus, cal0pteryx, Gonzalo Raúl Nemmi, Ludovic Bocquet, anubis, Badri (badrihippo), XSF iTeam
    • Translations:

      • French: Adrien Bourmault (neox), alkino, anubis, Arkem, Benoît Sibaud, mathieui, nyco, Pierre Jarillon, Ppjet6, Ysabeau
      • Italian: Mario Sabatino, Roberto Resoli

    Help us to build the newsletter

    This XMPP Newsletter is produced collaboratively by the XMPP community. Each month’s newsletter issue is drafted in this simple pad. At the end of each month, the pad’s content is merged into the XSF GitHub repository. We are always happy to welcome contributors. Do not hesitate to join the discussion in our XSF Communications Team group chat (MUC) and thereby help us sustain this as a community effort. You have a project and want to spread the news? Please consider sharing your news or events here, and promote it to a large audience.

    Tasks we do on a regular basis:

    • gathering news in the XMPP universe
    • short summaries of news and events
    • summary of the monthly communication on extensions (XEPs)
    • review of the newsletter draft
    • preparation of media images
    • translations
    • communication via media accounts

    Unsubscribe from the XMPP Newsletter

    For this newsletter either log in here and unsubscribe or simply send an email to newsletter-leave@xmpp.org. (If you have not previously logged in, you may need to set up an account with the appropriate email address.)

    License

    This newsletter is published under CC BY-SA license.

    • Pl chevron_right

      ProcessOne: Fluux Messenger 0.16.1: fixes and refinements from real-world use

      news.movim.eu / PlanetJabber • 16 June 2026 • 2 minutes

    Fluux Messenger 0.16.1: fixes and refinements from real-world use

    0.16.1 is our quick turnaround on that: a focused round offixes for the issues that have been reported, across encryption, connectivity,message history, and the desktop apps. Nothing dramatic here, we mainly want to show that we&aposre listening and addressing reported problems fast.

    End-to-end encryption in daily use

    With people now encrypting real conversations, a few practical details surfaced —and they&aposre sorted:

    • Verification works across clients. Fingerprints are published and compared in a consistent case (XEP-0373 expects upper-case), so the green "verified" lock appears reliably whatever XMPP client your contact uses.
    • Cleaner previews and placeholders. Encrypted reactions now show up properly in the conversation list, and you&aposll see a "decrypting…" placeholder while the encryption plugin finishes loading.
    • Complete archive. Encrypted messages without a plaintext body now come through correctly from server history (MAM).

    Smoother connections

    Field reports pointed to a handful of connection scenarios, now improved:

    • Happy Eyeballs. Fluux races IPv4 and IPv6 when connecting, so a slow or broken IPv6 route no longer holds things up, whichever answers first wins.
    • More reliable reconnection. Stream Management handling and the desktop&aposs local proxy hop were both tuned to resolve reconnection cases users reported.
    • Clearer status. Presence pills stay grey while reconnecting, and the reconnect spinner and countdown are back in the sidebar status chip for a calmer interface on unstable networks.

    More complete message history

    • Gap recovery. Some users reported missing stretches of history after long periods offline. Catch-up now closes those gaps in both group chats and 1:1 conversations, with a "load missing messages" marker to bring back anything that was skipped.
    • Reliable scroll-up. Loading older history by scrolling up now works as expected.

    A more polished desktop experience

    • Notifications open the right chat. On macOS, clicking a notification takes you straight to the conversation it belongs to.
    • Single window. Relaunching the app focuses the window that&aposs already running instead of opening a second copy.
    • Linux tray fallback. When the system tray isn&apost available, closing the window quits the app, so it can always be reopened.
    • Image downloads use the native save dialog, and Settings now links straight to your system notification settings.

    Lots of smaller fixes

    And plenty of smaller refinements from everyday use: consistent empty-state icons, reply quotes that match the original sender&aposs color and render as nested bars, opening a contact profile no longer bouncing you back, link-preview images that retry once before hiding, a smoother composer resize, local JID validation on the login screen, and group-chat performance improvements on room join.


    Thanks to everyone who reported issues and shared feedback – that&aposs exactly what shapes a release like this one. 0.16.1 is available now on our website , and the full changelog is on GitHub . Keep the reports coming!

    • Pl chevron_right

      ProcessOne: Fluux Messenger 0.16.0: End-to-End Encryption

      news.movim.eu / PlanetJabber • 11 June 2026 • 4 minutes

    Fluux Messenger 0.16.0: End-to-End Encryption

    Beyond that headline, the release also ships whisper messages, offline compose, unread badges, and a significant render-performance pass. Here is what changed and why.

    End-to-End Encryption with OpenPGP

    When end-to-end encryption is on, your messages are scrambled on your device before they leave it. Your XMPP server relays ciphertext, but it cannot read your conversations, even if the server is compromised or an administrator goes looking. The same applies to any relay between servers.

    Fluux implements OpenPGP for XMPP (XEP-0373, also called OX) — the modern redesign of OpenPGP encryption for XMPP. If you have come across XEP-0027 (the older "Current Jabber OpenPGP Usage"), that is a different, now-deprecated approach with well-documented weaknesses: no authenticated message envelope, signed-plaintext exposure, and no multi-device story. Fluux implements XEP-0373 only. It uses a proper content-encryption layer (XEP-0420) that authenticates the full message context and hides metadata from the server. It builds on the same OpenPGP cryptography used in encrypted email for decades, adapted correctly to instant messaging.

    Fluux Messenger 0.16.0: End-to-End Encryption

    Once you enable encryption in Settings → Encryption, your key pair is generated and your public key is published to your server. From that point, whenever a contact also has encryption enabled, Fluux automatically starts encrypting messages to them. A lock icon above the composer confirms it. Nothing to configure per conversation.

    Encrypted messages cover more than just text: reactions, edits, retractions, link previews, and file attachments all ride inside the same encrypted envelope. The server cannot see which emoji you reacted with, what you edited a message to say, or which files you shared.

    Why OpenPGP first?

    The choice of OpenPGP as the first E2EE protocol was deliberate, and it comes down to four practical properties.

    Multi-device without friction. A single OpenPGP key pair works across all your devices. You generate it once; every device you add simply loads the same key. There is no per-device key negotiation, no session bootstrapping required before encrypted history loads. This stands in contrast to ratchet-based protocols that issue a key per client installation and require all clients to exchange session state before decryption is possible.

    Encrypted backup you control. When you click Back up in the encryption settings, Fluux generates a backup code — 24 upper-case characters drawn from an unambiguous alphabet (no O or 0), grouped into 4-character chunks with dashes (e.g. TWNK-KD5Y-MT3T-E1GS-DRDB-KVTW). This format follows XEP-0373 §5.4 and is accepted by other compliant clients such as Gajim. Fluux encrypts your secret key with this code and stores the encrypted blob on your own XMPP server under a private node only you can access. The code never leaves your device.

    Fluux Messenger 0.16.0: End-to-End Encryption

    Your full history stays readable. Because every device shares the same key, messages encrypted months ago on one device remain decryptable on another. The server&aposs message archive (MAM) becomes a true history, not a graveyard of ciphertext only the originating device can open. Outgoing messages are also encrypted to your own key, so your sent history is fully accessible on every device.

    Simple, comprehensible verification. Trust On First Use (TOFU) gives you safe, convenient defaults. When you want a stronger guarantee, you compare fingerprints out-of-band, i.e. in person, over a phone call, on a separate verified channel. The fingerprint lives in the tooltip on the lock icon and in Settings → Encryption. You verify once per contact, per key, and you are done.

    Whisper messages — private threads inside group chats


    It is now possible to reply privately to a single occupant of a room without leaving the room. These whisper messages follow XEP-0045 §7.5 and appear in a distinct private thread so it is always clear they are not visible to the room at large.

    Fluux Messenger 0.16.0: End-to-End Encryption

    Other improvements worth knowing


    Compose while offline. Messages typed before a connection is established are queued locally and sent as soon as the session comes online.

    Connection status banner. A banner now appears while the app is reconnecting, so you always know when you are temporarily offline rather than wondering whether a message failed to send.

    Render-performance pass. This release eliminates a class of re-render storms that affected the conversation list, command palette, room config modals, occupant panel, roster, search, and individual message rows during background sync and group-chat presence churn. The result is a noticeably smoother experience on busy accounts.

    XMPP Console cleanup. Stream Management packets are now hidden by default in the developer XMPP console. The toggle remains available for when you need to trace them.

    What comes next for encryption

    The encryption engine is a plugin layer sitting between the XMPP client and the UI. OpenPGP is the first plugin loaded into that framework. Adding a second protocol means writing a new plugin that implements the same interface: key management, encrypt, decrypt, trust state. The rest of the app — message routing, UI indicators, backup flow — does not need to change.

    This matters because no single protocol wins every use case. OpenPGP&aposs shared-key model is ideal for multi-device history access; ratchet-based protocols like OMEMO excel at forward secrecy on single-device deployments; MLS is designed for large groups where pairwise key agreement would be impractical. The plan is to support several, letting users and deployments choose.

    The framework is in place; the question is which protocol to add second. OMEMO (XEP-0384) is the most widely deployed XMPP encryption protocol today. Adding it would maximise interoperability with existing XMPP clients. MLS (RFC 9420) is the newer IETF standard, designed from the ground up for multi-device and group scenarios, and is where the industry is heading long term.

    We have not decided yet. If you have a strong opinion, whether you are running an ejabberd deployment or just a user who cares, we would genuinely like to hear it. Just comment under that blog post.

    Release notes and download

    Full changelog on GitHub. Desktop builds for macOS, Windows, and Linux — plus the web version — are available on the ProcessOne website.