Message Delivery Receipts

Matthew M
Added over 5 years ago

Hello Tigase Team,

I wonder Is there any good way the confirm the successful delivery of a message to the recipient?

For example, the Facebook Messenger has status for each (last) message as "Delivered" and "Read", which is pretty useful

to confirm that a message is received, and/or read by the recipient. Are these two status supported by XMPP?

I did not find any XMPP spec to support "Read" by recipient status, do you know if it is a customized protocol?

But I do find a spec for "Delivered" status: Message Delivery Receipts,

I wonder if Tigase support this? Or is there any other better way to confirm the delivery?

As I am not sure if this XEP 184 is the right one, it says:

Because of these significant limitations, this protocol does not 
provide complete or even partial reliability or guaranteed delivery.

In this case, which spec should we follow to guarantee the delivery, if there is any? Or how does Tigase deal with it?

Many thanks for your help!

Replies (3)


Added by Artur Hefczyc TigaseTeam over 5 years ago

First you have to distinguish between delivery reliability (guaranteed delivery) and delivery confirmation. At first they sounds like the same or very similar when in fact they are very different things.

  1. Delivery confirmation gives you... well confirmation that something has been delivered or read or open or something happened. And it also gives you an idea of when this something happened. It is not about what happens when you do not receive a message or a confirmation. And actually lack of receiving delivery confirmation does not mean the message was not delivered. It could be that the confirmation was lost for example or the recipient was offline or something else happened. It does not say you either, whether there will be another attempt to deliver the message and so on... Usually there is not notification that the delivery was unsuccessful.

  2. "Guaranteed delivery" is about making sure the packet is delivered. Usually the protocol also specifies a timeframe for the message delivery to consider it successful. Usually confirmation to the end-user is not necessary and implemented because if the protocol guarantees message delivery, the message will be delivered. Sometimes there is notification for unsuccessful delivery.

There are different requirements for different use-cases, hence there are different protocols and extensions available.

  1. For guaranteed delivery we have Stream Management extension introduces protocol level ACKs for confirming packet delivery on line between a client and a server. This gives you quite good assurance that none of the packet is lost and if the user ever comes online and his offline message storage is not overfilled he will eventually receive the message. (See how many *if*s are still there?

  2. For delivery status we also have quite a few extensions: Advanced Message Processing Message Delivery Receipts Chat State Notifications Each has a different purpose and should be used for a different use-case.

Both the XEP-0198 and XEP-0079 are supported by the Tigase server. Other extensions are for the client side software only.

Added by Matthew M over 5 years ago

Many thanks to the thorough explanation and it makes a lot of sense!

  1. How to enable "Stream Management" on the server side?

  2. By reading the Tigase code I found this method: "sendAck(Packet packet) ".

I wonder is this something related to any XMPP protocol? The packet is sending string "ACK" back on some condition, but it seems that this is not the same as in "Stream Management", so I wonder is this some other spec, and is this serve the purpose of "guaranteed delivery", and how do I enable this feature?

    private void sendAck(Packet packet) 

        // If stanza receiving confirmation is configured, try to send confirmation
        // back
        if (white_char_ack || xmpp_ack) {
            String ack = null;

            if (white_char_ack) {

                // If confirming via white space is enabled then prepare space ack.
                ack = " ";
            if (xmpp_ack) {
                Element req = packet.getElement().getChild(REQ_NAME);

                if (req != null) {

                    String req_val = req.getAttributeStaticStr(ID_ATT);

                    if (req_val != null) {

                        // XMPP ack might be enabled in configuration but the client may not
                        // support it. In such a case we do not send XMPP ack.
                        ack = "<" + ACK_NAME + " " + ID_ATT + "=\"" + req_val + "\"/>";
            if (ack != null) {
                try {
                    log.log(Level.FINEST, "Sent ack confirmation: '" + ack + "'");
                } catch (Exception ex) {
                    log.log(Level.FINE, "Can't send ack confirmation: '" + ack + "'", ex);


Added by Artur Hefczyc TigaseTeam over 5 years ago

Do not read the code, just follow the spec. Stream management on Tigase 5.2.0 is available by default but the client has to activate it for the connection. Just follow the spec. Note, it is available from version 5.2.0 beta3.