Acknowledging Messages Received by Clients

The messaging APIs provide acknowledgments to the PubSub+ event broker for the guaranteed messages that clients receive through a Flow. The figure below shows the process of how the guaranteed messages that an application receives through a Flow are acknowledged. During this Flow, client applications can also send a negative acknowledgment (Nack) for malformed messages or messages that could not be processed.

Acknowledging Received Guaranteed Messages

API Acknowledgments

A Guaranteed Message window size limits the number of messages that the API can receive before it must return an acknowledgment to the event broker to indicate that it received the messages in the window. After the API sends this acknowledgment, the Guaranteed Message window reopens so that further messages can be sent to the API.

An application can adjust the windowed acknowledgments by changing the default acknowledgment timer and threshold parameters set through the Flow properties (refer to Important Flow (Message Consumer) Properties). Changing these defaults is not usually required and will change the performance characteristics of a Flow.

Application Acknowledgments

One of the two following application acknowledgment modes can be used for acknowledging a message:

  • Auto-acknowledgment
  • Client acknowledgment

The acknowledgment mode to use is set through one of the flow properties listed below. By default, the auto-acknowledgment mode is used. 

The following table shows how to perform acknowledgment for the different APIs:

PubSub+ Messaging API Use


ConsumerFlowProperties.setAckMode(String ackMode)

Possible values are:



Java RTO


Possible values in SolEnum.AckMode are:

  • AckMode.AUTO

  • AckMode.CLIENT






Possible values are:

  • AutoAck

  • ClientAck

JavaScript and Node.js


Possible values are:

  • solace.MessageConsumerAcknowledgeMode.AUTO

  • solace.MessageConsumerAcknowledgeMode.CLIENT

Auto-Acknowledgment Mode

When the auto-acknowledgment mode is used, the API automatically generates application-level acknowledgments.

For JCSMP, acknowledgments are sent at different types depending on whether the message is received asynchronously or synchronously:

  • when received asynchronously, the acknowledgment is sent after the message callback completes.
  • when received synchronously, the acknowledgment is sent after the message is removed from the API's internal queue during the receive() method. It's important to realize that the acknowledgment has been sent before control is returned to the application (that is after the receive() method completes).

Client Acknowledgment Mode

When the client acknowledgment mode is used the client must explicitly send an acknowledgment for the message ID of each message received.

To explicitly send a client acknowledgment, call one of the methods or functions listed below.

Avoid allowing the number of outstanding unacknowledged messages to become excessively large (for example, 10,000 or more) because the egress message rate from the event broker can start to decline.

To send an Explicit Client Acknowledgment

PubSub+ Messaging API Use



Java RTO


See the PubSub+ Messaging API for JRTO for information





JavaScript and Node.js


Acknowledgment is called on the message object.

When using the client acknowledgment mode with the C API, the maximum number of messages that the API can deliver to the application through the Flow without receiving client acknowledgments can be set through the SOLCLIENT_FLOW_PROP_MAX_UNACKED_MESSAGES Flow property. By default, this property has a value of -1, which specifies that the maximum number of unacknowledged messages that can be delivered is not restricted by the API. (To change the maximum number of unacknowledged messages that may be received through an existing Flow, call solClient_flow_setMaxUnacked()).

Negative Acknowledgments for Specific Messages

Consumer applications can send an acknowledgment (ACK) or a negative acknowledgment (Nack) based on the settlement outcome of processing a guaranteed message. Rather than send an explicit acknowledgment (Ack) (as described in Client Acknowledgment Mode), you can signal (via a settle method/function) a settlement outcome to the event broker. The default outcome that's available is ACCEPTED, which signals an acknowledgment (Ack) of a message to the event broker. For negative acknowledgments, you can send FAILED or REJECTED.

To use NACKs, you must add the FAILED, REJECTED, or both as NACK types prior to creating the Flow. Adding the NACK types prepares the Flow to work with negative acknowledgments. Based on the settlement outcome of the negative acknowledgment received, the event broker can:

  • attempt to redeliver the message (while adhering to delivery count limits) for FAILED outcomes
  • move the message to the Dead Message Queue (DMQ) if available, otherwise delete message for REJECTED outcomes
  • It is possible that Nacks sent by consumer applications to be lost during transit (for example due to unexpected networking issues). Consider this as part of your application development for processing messages.
  • Nacks are supported on event brokers 10.2.1 and later. If an event broker does not support Nacks, an InvalidOperationException occurs during the Flow bind request when an outcome is specified.
PubSub+ Messaging API Calls


ConsumerFlowProperties.addRequiredSettlementOutcomes(Outcome outcometoadd)


Possible values to use:

  • Outcome.ACCEPTED
  • Outcome.FAILED
  • Outcome.REJECTED

Java RTO

Not supported.


Not supported.


Not supported.

JavaScript and Node.js

Not supported.

Using Nacks with the JCSMP API

The following sample code shows how to send Nacks using the PubSub+ Messaging API for JCSMP:

// A session has alredy been created with JCSMPProperties.SUPPORTED_MESSAGE_ACK_CLIENT
final ConsumerFlowProperties cfp = new ConsumerFlowProperties().setEndpoint(q);

// Add the settlement outcomes - Outcome.ACCEPTED does not need to be added because it is always included
// The consumer can add multiple outcomes, for example cfp.addRequiredSettlementOutcomes(Outcome.FAILED, Outcome.REJECTED);

final FlowReceiver flowReceiver= session.createFlow(null, cfp);
BytesXMLMessage msg = flowReceiver.receive(1000);
try {
    msg.settle(Outcome.ACCEPTED);// same as msg.ackMessage();  
    catch (Exception e){
        msg.settle(Outcome.FAILED); // Failed to process message, settle as FAILED