diff --git a/apps/emqx_message_validation/src/emqx_message_validation.erl b/apps/emqx_message_validation/src/emqx_message_validation.erl
index 8bf0b879e..74de48eac 100644
--- a/apps/emqx_message_validation/src/emqx_message_validation.erl
+++ b/apps/emqx_message_validation/src/emqx_message_validation.erl
@@ -383,6 +383,12 @@ run_validations(Validations, Message) ->
case run_validation(Validation, Message) of
ok ->
{cont, Acc};
+ ignore ->
+ trace_failure(Validation, "validation_failed", #{
+ validation => Name,
+ action => ignore
+ }),
+ {cont, Acc};
FailureAction ->
trace_failure(Validation, "validation_failed", #{
validation => Name,
diff --git a/apps/emqx_message_validation/src/emqx_message_validation_schema.erl b/apps/emqx_message_validation/src/emqx_message_validation_schema.erl
index cd1711e0a..618b73481 100644
--- a/apps/emqx_message_validation/src/emqx_message_validation_schema.erl
+++ b/apps/emqx_message_validation/src/emqx_message_validation_schema.erl
@@ -75,7 +75,7 @@ fields(validation) ->
)},
{failure_action,
mk(
- hoconsc:enum([drop, disconnect]),
+ hoconsc:enum([drop, disconnect, ignore]),
#{desc => ?DESC("failure_action"), required => true}
)},
{log_failure,
diff --git a/apps/emqx_message_validation/test/emqx_message_validation_http_api_SUITE.erl b/apps/emqx_message_validation/test/emqx_message_validation_http_api_SUITE.erl
index e3207320f..141fc74af 100644
--- a/apps/emqx_message_validation/test/emqx_message_validation_http_api_SUITE.erl
+++ b/apps/emqx_message_validation/test/emqx_message_validation_http_api_SUITE.erl
@@ -573,9 +573,31 @@ t_log_failure_none(_Config) ->
),
ok.
+t_action_ignore(_Config) ->
+ ?check_trace(
+ begin
+ Name1 = <<"foo">>,
+ AlwaysFailCheck = sql_check(<<"select * where false">>),
+ Validation1 = validation(
+ Name1,
+ [AlwaysFailCheck],
+ #{<<"failure_action">> => <<"ignore">>}
+ ),
+ {201, _} = insert(Validation1),
+ C = connect(<<"c1">>),
+ {ok, _, [_]} = emqtt:subscribe(C, <<"t/#">>),
+ ok = publish(C, <<"t/1">>, #{}),
+ ?assertReceive({publish, _}),
+ ok
+ end,
+ fun(Trace) ->
+ ?assertMatch([#{action := ignore}], ?of_kind(message_validation_failure, Trace)),
+ ok
+ end
+ ),
ok.
%% Check the `all_pass' strategy
diff --git a/rel/i18n/emqx_message_validation_schema.hocon b/rel/i18n/emqx_message_validation_schema.hocon
index be746368a..670a16b80 100644
--- a/rel/i18n/emqx_message_validation_schema.hocon
+++ b/rel/i18n/emqx_message_validation_schema.hocon
@@ -71,7 +71,8 @@ emqx_message_validation_schema {
"""How to proceed if the validation fails.
drop: The offending message is simply dropped without further processing.
- disconnect: The message is not published, and the publishing client is disconnected."""
+ disconnect: The message is not published, and the publishing client is disconnected.
+ ignore: Only the failure is logged and traced. No other action is taken."""
failure_action.label:
"""Failure action"""