Stream Management counter error

Hey,

I´m trying to reconnect the client if the network connection was lost. I´m using the ReconnectionManager and the reconnection works. But after the connection is established, I get an error with Stream Managment counters, and the ReconnectionManager reconnects the client. This ends in a loop.

This is the error output (No outstanding stanzas):

03-08 13:55:40.864 2450-3936/io.**** D/SMACK: XMPPConnection authenticated (XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0)) and resumed
03-08 13:33:11.274 22158-23332/io.*** D/XCS: Connection established in Service!
03-08 13:33:11.274 22158-23332/io**** D/SMACK: XMPPConnection connected (XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0))
03-08 13:33:11.284 22158-23412/io.*** W/AbstractXMPPConnection: Connection XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0) closed with error
                                                                                     org.jivesoftware.smack.sm.StreamManagementException$StreamManagementCounterError: There was an error regarding the Stream Mangement counters. Server reported 24 handled stanzas, which means that the 3 recently send stanzas by client are now acked by the server. But Smack had only 2 to acknowledge. The stanza id of the last acked outstanding stanza is buCOa-61
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection.processHandledCount(XMPPTCPConnection.java:1857)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2600(XMPPTCPConnection.java:150)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1161)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:982)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:998)
                                                                                         at java.lang.Thread.run(Thread.java:818)

This error is also shown:

03-08 13:55:40.864 2450-3936/io.**** D/SMACK: XMPPConnection authenticated (XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0)) and resumed
03-08 13:46:14.164 28560-30207/io.*** D/XCS: Connection established in Service!
03-08 13:46:14.164 28560-30207/io.**** D/SMACK: XMPPConnection connected (XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0))
03-08 13:46:14.174 28560-30238/io.***** W/AbstractXMPPConnection: Connection XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0) closed with error
                                                                                     org.jivesoftware.smack.sm.StreamManagementException$StreamManagementCounterError: There was an error regarding the Stream Mangement counters. Server reported 36 handled stanzas, which means that the 3 recently send stanzas by client are now acked by the server. But Smack had only 0 to acknowledge. The stanza id of the last acked outstanding stanza is <no acked stanzas>
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection.processHandledCount(XMPPTCPConnection.java:1857)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2600(XMPPTCPConnection.java:150)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1161)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:982)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:998)
                                                                                         at java.lang.Thread.run(Thread.java:818)

This error spawns randomly.
How can I avoid that?

Thanks in advance.

We need to find out if it’s a client or server issue. What server do you use? Which Smack version?

By fixing the issue or disabling Stream Management.

I´m using a MongooseIM server and Smack version is 4.2.0.

My configuration on client side is the following:

    private void initializeConnection() {
        XMPPTCPConnectionConfiguration config = null;
        try{
            XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder()
                    .setXmppDomain(JidCreate.domainBareFrom("localhost"))
                    .setHostAddress(getInetAddress())
                    .setPort(PORT)
                    .setCompressionEnabled(false)
                    .setResource("test")
                    .setDebuggerEnabled(XMPP_DEBUG_MODE)      // Disable in production, because it blocks the UI thread heavily
                    .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);

            config = builder.build();

        }catch (XmppStringprepException e){
            XMPPErrorHandler.handleXMPPError(e);
        }

        //XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
        //XMPPTCPConnection.setUseStreamManagementDefault(true);
        mXMPPConnection = new XMPPTCPConnection(config);
        mXMPPConnection.setUseStreamManagement(true);
        mXMPPConnection.setUseStreamManagementResumption(true);
        mXMPPConnection.addRequestAckPredicate(new SMAskPredicate());

        // Listens to the network connectivity
        mXMPPConnection.addConnectionListener(new ConnectionListener() {
            @Override
            public void connected(XMPPConnection connection) {
                Log.w(XMPP_TAG, "Connection Successful");
                if(!mXMPPConnection.isAuthenticated()){
                    login();
                }

                if(mXMPPConnection.isAuthenticated()){
                    mListener.onConnectionEstablished(mXMPPConnection);
                }
            }

            @Override
            public void authenticated(XMPPConnection connection, boolean resumed) {
                Log.w(XMPP_TAG, "authenticated");
                Preferences.getInstance().setLoggedIn(true);
                sendPresenceAvailable();
                setXMPPListeners();
                loadMAMMessages();
                if(mXMPPConnection.isAuthenticated()){
                    mListener.onConnectionEstablished(mXMPPConnection);
                }
            }

            @Override
            public void connectionClosed() {

            }

            @Override
            public void connectionClosedOnError(Exception e) {

            }

            @Override
            public void reconnectionSuccessful() {
            }

            @Override
            public void reconnectingIn(int seconds) {
                Log.w(XMPP_TAG, "Re-Connecting...");
                disconnect();
            }

            @Override
            public void reconnectionFailed(Exception e) {
                disconnect();
                setXMPPListeners();
                Log.w(XMPP_TAG, "Re-Connection failed");
                //connect();
            }
        });

        // Reconnection Manager
        mReconnectionManager = ReconnectionManager.getInstanceFor(mXMPPConnection);
        mReconnectionManager.setReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.RANDOM_INCREASING_DELAY);
        mReconnectionManager.enableAutomaticReconnection();

        // Keeps TCP Connection alive
        ServerPingWithAlarmManager.onCreate(mContext);
        ServerPingWithAlarmManager.getInstanceFor(mXMPPConnection).setEnabled(true);

        setXMPPListeners(); // Add listeners


        // Ping Manager (Pings the XMPP Server every 5 minutes to check if the client is still connected)
        PingManager pingManager = PingManager.getInstanceFor(mXMPPConnection);
        pingManager.setPingInterval(300);
        pingManager.pingServerIfNecessary();
        pingManager.registerPingFailedListener(new PingFailedListener() {
            @Override
            public void pingFailed() {
                disconnect();
                initializeConnection();
            }
        });

The Stream Managment configuration on server is the following:

  {mod_stream_management, [
                           % default 100
                           % size of a buffer of unacked messages
                           {buffer_max, 100},

                           % default 1 - server sends the ack request after each stanza
                           {ack_freq, 1},

                           % default: 600 seconds
                           {resume_timeout, 600}
                          ]},

It is impossible to determine if it’s a client or server error witout an XMPP trace starting from the second last ack to the last ack received (from the client’s POV).

I tested something around and found out, if I want to access the MAM the error gets thrown.

Here is the stacktrace:

D/SMACK: SENT (0): <iq id='0vLr1-335' type='set'><query xmlns='urn:xmpp:mam:1' queryid='827da5c7-a133-4b57-a41e-67e6d159a5c4'><x xmlns='jabber:x:data' type='submit'><field var='FORM_TYPE' type='hidden'><value>urn:xmpp:mam:1</value></field><field var='start'><value>2018-03-08T14:47:55.351+00:00</value></field></x></query></iq><r xmlns='urn:xmpp:sm:3'/><presence to='hdzy4zzdp3@localhost/test' id='0vLr1-336'><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.igniterealtime.org/projects/smack' ver='p801v5l0jeGbLCy09wmWvQCQ7Ok='/></presence><r xmlns='urn:xmpp:sm:3'/>
W/System.err: org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 5000ms (~5s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=0vLr1-335)), : fromFilter (OrFilter: (FromMatchesFilter (full): null, FromMatchesFilter (ignoreResourcepart): hdzy4zzdp3@localhost, FromMatchesFilter (full): localhost)).
W/System.err:     at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:253)
W/System.err:     at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:208)
W/System.err:     at org.jivesoftware.smackx.mam.MamManager.queryArchive(MamManager.java:528)
W/System.err:     at org.jivesoftware.smackx.mam.MamManager.queryArchive(MamManager.java:273)
W/System.err:     at org.jivesoftware.smackx.mam.MamManager.queryArchiveWithStartDate(MamManager.java:191)

These are the two stanzas which are not get acked by the server:

03-08 15:48:12.074 20434-24040/ D/SMACK: XMPPConnection connected (XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0))
03-08 15:48:12.074 20434-24103/r W/AbstractXMPPConnection: Connection XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0) closed with error
                                                                                     org.jivesoftware.smack.sm.StreamManagementException$StreamManagementCounterError: There was an error regarding the Stream Mangement counters. Server reported 77 handled stanzas, which means that the 4 recently send stanzas by client are now acked by the server. But Smack had only 2 to acknowledge. The stanza id of the last acked outstanding stanza is 0vLr1-334
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection.processHandledCount(XMPPTCPConnection.java:1857)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2600(XMPPTCPConnection.java:150)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1161)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:982)
                                                                                         at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:998)
                                                                                         at java.lang.Thread.run(Thread.java:818)

03-08 15:48:12.074 20434-24103/D/SMACK: XMPPConnection closed due to an exception (XMPPTCPConnection[hdzy4zzdp3@localhost/test] (0))
                                                                    org.jivesoftware.smack.sm.StreamManagementException$StreamManagementCounterError: There was an error regarding the Stream Mangement counters. Server reported 77 handled stanzas, which means that the 4 recently send stanzas by client are now acked by the server. But Smack had only 2 to acknowledge. The stanza id of the last acked outstanding stanza is 0vLr1-334
                                                                        at org.jivesoftware.smack.tcp.XMPPTCPConnection.processHandledCount(XMPPTCPConnection.java:1857)
                                                                        at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2600(XMPPTCPConnection.java:150)
                                                                        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1161)
                                                                        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:982)
                                                                        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:998)
                                                                        at java.lang.Thread.run(Thread.java:818)

Smack has only logged this for stream resumption:

03-08 15:47:20.044 20434-23701 D/SMACK: SENT (0): <a xmlns='urn:xmpp:sm:3' h='108'/>
03-08 15:47:33.624 20434-23900/D/SMACK: RECV (0): <a xmlns='urn:xmpp:sm:3' h='73'/><a xmlns='urn:xmpp:sm:3' h='73'/>
03-08 15:47:33.624 20434-23900/ D/SMACK: RECV (0): <a xmlns='urn:xmpp:sm:3' h='74'/>

Is it possible to prevent to send stanzas after a reconnection to avoid that issue?
Because if I restart my “Service (sticky)”, then all is working fine, but I can´t catch the StreamManagementCounterError to restart my “Service”.

BTW: The server does not have any logs, where this error is documented.