In messaging, acknowledgments (ACKs) play a pivotal role, serving as assurances that messages have been successfully received and processed. This simple act of confirmation forms the backbone of reliable messaging systems by ensuring that no piece of information slips through unnoticed. However, not all communications proceed flawlessly, and this is where negative acknowledgments (NACKs) enter the scene.

Unlike their affirmative counterparts, NACKs signal the inability to process a message due to issues such as errors, resource constraints, or data corruption. They are essential for maintaining data integrity and system robustness, allowing the receiver to let the event broker know the result from processing a guaranteed message whether to discard or retry transmissions.

The Importance of Message Acknowledgements (ACKs)

The messaging APIs provide acknowledgments to the PubSub+ event broker for the guaranteed messages that clients receive through a flow. This diagram shows how the guaranteed messages that an application receives through a flow are acknowledged. During this flow, client applications can also send a NACK for malformed messages, or messages that could not be processed.

guaranteed messages that an application receives through a flow are acknowledged

Application Acknowledgements

Application acknowledgements tell the event broker that the application is done processing the message and that it can be removed from the queue or topic endpoint. You can acknowledge a message with one of two modes:

  • Auto Acknowledgment: The default mode of acknowledgment in Solace. When using Auto Ack, the acknowledgment to the broker is sent automatically as soon as the consumer receives the message. The API automatically generates application-level acknowledgements – a settlement with ACCEPTED outcome.
  • Client Acknowledgment: This mode requires the consumer to explicitly acknowledge messages once they have been successfully processed. This mode gives the application control over the acknowledgment process, allowing for more robust handling of messages with control over the suitable type of settlement.

Settlements

Settlements serve as a crucial mechanism that allows consumers to inform the broker about the successful or unsuccessful processing of a message. It is a mechanism available for the consumers to let the broker know whether a message was successfully processed or not. If it failed to process successfully, what is expected of the broker – resend the message or remove the message from the queue. As part of the message processing flow, a consumer can send a settlement outcome indicating the desired action.

The Three Kinds of Settlements

  • ACCEPTED – Notifies the event broker that your client application successfully processed the guaranteed message, and the message can be removed from the queue.
  • FAILED – This NACK notifies the event broker that your client application did not process the message. When the event broker receives this NACK it attempts to redeliver the message while adhering to delivery count limits.
  • REJECTED – This NACK notifies the event broker that your client application could process the message, but it was not accepted (for example, failed validation). When the event broker receives this NACK it removes the message from its queue and then moves the message to the Dead Message Queue (DMQ) if it is configured.

Negative Acknowledgement (NACK)

When the client acknowledgment mode is used, the client can use NACKs to send a settlement outcome to let the event broker know the result from processing a guaranteed message that was received. The settlement outcomes that are interest for a negative acknowledgment are FAILED and REJECTED.

Before you can utilize NACKs, you need to include FAILED, REJECTED, or both as NACK types when setting up the flow. The ACCEPTED outcome does not need to be added since it is always available. Attempting to use an outcome that hasn’t been incorporated into the flow will result in a “Required Settlement Outcome Not Supported” error.

An example use of NACK in Solace JCSMP API:

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

// Outcome.ACCEPTED does not need to be added because it is always included
// Add the settlement outcomes for Outcome.FAILED & Outcome.REJECTED
// 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);
if (validateMessage(msg)) {
    msg.settle(Outcome.REJECTED); // Failed validation, settle as REJECTED
    return;
}

try {
    processMessage(msg);
    msg.settle(Outcome.ACCEPTED);// optional - same as msg.ackMessage();  
} catch (Exception e) {
    msg.settle(Outcome.FAILED); // Failed processing, settle as FAILED
    return;
}
...
...

NOTE: NACKs can be lost during transit (for example due to unexpected networking issues). Consider this fact as part of the logic for handling messages when you develop your application. NACK is supported on event brokers 10.2.1 and later in JCSMP, Java RTO, C, .NET, JavaScript, and Node.js APIs. If an event broker does not support NACKs, an InvalidOperationException is thrown at the flow bind request when an outcome is specified.

The Benefits of Negative Acknowledgements (NACKs)

NACKs serve a critical role in ensuring data integrity and robust message handling in messaging. Here’s how they add value to businesses:

  • Greater Reliability: Messages may fail to process due to various reasons such as logical errors, or data inconsistencies. NACKs allow a service to signal that it could not process a message successfully. This acknowledgment triggers broker to take corrective actions, such as retrying the message delivery or redirecting the message to a dead message queue, thereby enhancing the reliability of the system.
  • Smoother Error Handling: NACKs facilitate improved error handling mechanisms. When a consumer cannot process a message correctly (due to data corruption, missing information, or any logic conditions not being met), it can send a NACK. This feedback loop helps in isolating problematic messages and managing them appropriately.
  • More Resilience: By implementing NACKs, systems can be designed to be more resilient. They enable a consumer to reject messages without halting the entire processing pipeline. This feature is crucial for maintaining service availability and performance.
  • Better Flow Control: NACKs can act as a mechanism for flow control. They prevent a consumer from being overwhelmed by messages it cannot process at the moment. This can be critical in scenarios where message producers can send messages at a faster rate than consumers can process them.

Conclusion

Acknowledgments and negative acknowledgements serve as vital signals to the broker regarding the status of message processing and dictate whether a message should be retained or removed from the queue. The settlement mechanism simplifies this process by clearly delineating the desired outcomes. Through settlements, systems can efficiently convey whether a message was successfully processed or encountered issues.

To guide your implementation, consider the following standard outcomes:

  • ACCEPTED: This positive acknowledgment signifies that the message has been processed successfully and can be removed from the queue.
  • FAILED: This negative acknowledgment indicates that the message was not successfully processed but should be retried, leveraging the broker’s message redelivery capabilities.
  • REJECTED: This outcome is used when a message cannot be processed due to errors such as validation or logical faults, recommending its removal from the queue.

Integrating both ACKs and NACKs with the use of appropriate settlements ensures that every message is accounted for, making it a critical practice for businesses reliant on continuous real-time data flow and high system reliability. This serves as a foundation to enhance the effectiveness and reliability of your messaging system.

You can check out the manual message acknowledgment sample in our Git repository:

And these are great places to learn more about ACKs and NACKs:

Last but not least, be sure to check out Solace Community, where developers and our own product experts exchange ideas, share thoughts, and discuss topics related to event-driven architecture.

Giri Venkatesan
Giri Venkatesan

Giri is a developer advocate with extensive experience in various technical domains, including integration and master data management. He started his engineering journey in the classic EAI & B2B Integration space and has been a part of the integration evolution culminating in modern EDA, microservices, Spring, and other low-code/no-code frameworks. He has a keen interest in building and promoting creative solutions and is a huge fan of open-source standards and applications. He is excited to identify and explore tools and frameworks to aid businesses in their quest for achieving efficiency and increased productivity.