diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 1fe79fb..ddb23fd 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -302,8 +302,6 @@ acl_add_ptr(struct acl_build_context *context,
 		/* add room for more pointers */
 		num_ptrs = node->max_ptrs + ACL_PTR_ALLOC;
 		ptrs = acl_build_alloc(context, num_ptrs, sizeof(*ptrs));
-		if (ptrs == NULL)
-			return -ENOMEM;
 
 		/* copy current points to new memory allocation */
 		if (node->ptrs != NULL) {
@@ -477,16 +475,12 @@ acl_dup_node(struct acl_build_context *context, struct rte_acl_node *node)
 	struct rte_acl_node *next;
 
 	next = acl_alloc_node(context, node->level);
-	if (next == NULL)
-		return NULL;
 
 	/* allocate the pointers */
 	if (node->num_ptrs > 0) {
 		next->ptrs = acl_build_alloc(context,
 			node->max_ptrs,
 			sizeof(struct rte_acl_ptr_set));
-		if (next->ptrs == NULL)
-			return NULL;
 		next->max_ptrs = node->max_ptrs;
 	}
 
@@ -669,8 +663,6 @@ acl_merge_intersect(struct acl_build_context *context,
 
 	/* Duplicate A for intersection */
 	node_c = acl_dup_node(context, node_a->ptrs[idx_a].ptr);
-	if (node_c == NULL)
-		return -1;
 
 	/* Remove intersection from A */
 	acl_exclude_ptr(context, node_a, idx_a, intersect_ptr);
@@ -1328,14 +1320,10 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
 	rule = head;
 
 	trie = acl_alloc_node(context, 0);
-	if (trie == NULL)
-		return NULL;
 
 	while (rule != NULL) {
 
 		root = acl_alloc_node(context, 0);
-		if (root == NULL)
-			return NULL;
 
 		root->ref_count = 1;
 		end = root;
@@ -1419,10 +1407,9 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
 		 * Setup the results for this rule.
 		 * The result and priority of each category.
 		 */
-		if (end->mrt == NULL &&
-				(end->mrt = acl_build_alloc(context, 1,
-				sizeof(*end->mrt))) == NULL)
-			return NULL;
+		if (end->mrt == NULL)
+			end->mrt = acl_build_alloc(context, 1,
+				sizeof(*end->mrt));
 
 		for (m = 0; m < context->cfg.num_categories; m++) {
 			if (rule->f->data.category_mask & (1 << m)) {
@@ -1760,13 +1747,6 @@ acl_build_tries(struct acl_build_context *context,
 
 		/* Create a new copy of config for remaining rules. */
 		config = acl_build_alloc(context, 1, sizeof(*config));
-		if (config == NULL) {
-			RTE_LOG(ERR, ACL,
-				"New config allocation for %u-th "
-				"trie failed\n", num_tries);
-			return -ENOMEM;
-		}
-
 		memcpy(config, rule_sets[n]->config, sizeof(*config));
 
 		/* Make remaining rules use new config. */
@@ -1825,12 +1805,6 @@ acl_build_rules(struct acl_build_context *bcx)
 	sz = ofs + n * fn * sizeof(*wp);
 
 	br = tb_alloc(&bcx->pool, sz);
-	if (br == NULL) {
-		RTE_LOG(ERR, ACL, "ACL context %s: failed to create a copy "
-			"of %u build rules (%zu bytes)\n",
-			bcx->acx->name, n, sz);
-		return -ENOMEM;
-	}
 
 	wp = (uint32_t *)((uintptr_t)br + ofs);
 	num = 0;
@@ -1895,6 +1869,16 @@ acl_bld(struct acl_build_context *bcx, struct rte_acl_ctx *ctx,
 	bcx->category_mask = LEN2MASK(bcx->cfg.num_categories);
 	bcx->node_max = node_max;
 
+	rc = sigsetjmp(bcx->pool.fail, 0);
+
+	/* build phase runs out of memory. */
+	if (rc != 0) {
+		RTE_LOG(ERR, ACL,
+			"ACL context: %s, %s() failed with error code: %d\n",
+			bcx->acx->name, __func__, rc);
+		return rc;
+	}
+
 	/* Create a build rules copy. */
 	rc = acl_build_rules(bcx);
 	if (rc != 0)
diff --git a/lib/librte_acl/tb_mem.c b/lib/librte_acl/tb_mem.c
index fdf3080..157e608 100644
--- a/lib/librte_acl/tb_mem.c
+++ b/lib/librte_acl/tb_mem.c
@@ -37,6 +37,11 @@
  *  Memory management routines for temporary memory.
  *  That memory is used only during build phase and is released after
  *  build is finished.
+ *  Note, that tb_pool/tb_alloc() are not supposed to return NULL.
+ *  Instead, in the case of failure to allocate memory,
+ *  it would do siglongjmp(pool->fail).
+ *  It is responsibility of the caller to save the proper context/environment,
+ *  in the pool->fail before calling tb_alloc() for the given pool first time.
  */
 
 static struct tb_mem_block *
@@ -51,6 +56,7 @@ tb_pool(struct tb_mem_pool *pool, size_t sz)
 	if (block == NULL) {
 		RTE_LOG(ERR, MALLOC, "%s(%zu)\n failed, currently allocated "
 			"by pool: %zu bytes\n", __func__, sz, pool->alloc);
+		siglongjmp(pool->fail, -ENOMEM);
 		return NULL;
 	}
 
@@ -81,8 +87,6 @@ tb_alloc(struct tb_mem_pool *pool, size_t size)
 	if (block == NULL || block->size < size) {
 		new_sz = (size > pool->min_alloc) ? size : pool->min_alloc;
 		block = tb_pool(pool, new_sz);
-		if (block == NULL)
-			return NULL;
 	}
 	ptr = block->mem;
 	block->size -= size;
diff --git a/lib/librte_acl/tb_mem.h b/lib/librte_acl/tb_mem.h
index a8dae94..ca7af96 100644
--- a/lib/librte_acl/tb_mem.h
+++ b/lib/librte_acl/tb_mem.h
@@ -48,6 +48,7 @@ extern "C" {
 #endif
 
 #include <rte_acl_osdep.h>
+#include <setjmp.h>
 
 struct tb_mem_block {
 	struct tb_mem_block *next;
@@ -61,6 +62,8 @@ struct tb_mem_pool {
 	size_t               alignment;
 	size_t               min_alloc;
 	size_t               alloc;
+	/* jump target in case of memory allocation failure. */
+	sigjmp_buf           fail;
 };
 
 void *tb_alloc(struct tb_mem_pool *pool, size_t size);
