diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c
index ab8ae3d0c60e1a66cf5cd5b566f0fc73ec888db8..829d3d30e03d14648a5bcaf3e52df3f77468a9fe 100644
--- a/src/lib-sieve/plugins/regex/ext-regex.c
+++ b/src/lib-sieve/plugins/regex/ext-regex.c
@@ -13,7 +13,10 @@
 #include "sieve-code.h"
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
+
+#include "sieve-comparators.h"
 #include "sieve-match-types.h"
+
 #include "sieve-validator.h"
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
@@ -53,13 +56,17 @@ static bool ext_regex_load(int ext_id)
 
 extern const struct sieve_match_type_extension regex_match_extension;
 
+bool mtch_regex_validate_context
+(struct sieve_validator *validator, struct sieve_ast_argument *arg,
+    struct sieve_match_type_context *ctx);
+
 const struct sieve_match_type regex_match_type = {
 	"regex",
 	SIEVE_MATCH_TYPE_CUSTOM,
 	&regex_match_extension,
 	0,
 	NULL,
-	NULL,
+	mtch_regex_validate_context,
 	NULL
 };
 
@@ -69,6 +76,34 @@ const struct sieve_match_type_extension regex_match_extension = {
 	NULL
 };
 
+/* Validation */
+
+bool mtch_regex_validate_context
+(struct sieve_validator *validator, struct sieve_ast_argument *arg,
+	struct sieve_match_type_context *ctx)
+{
+	struct sieve_ast_argument *carg = 
+		sieve_command_first_argument(ctx->command_ctx);
+
+	while ( carg != NULL ) {
+		if ( carg != arg && carg->argument == &comparator_tag ) {
+			if (!sieve_comparator_tag_is(carg, &i_ascii_casemap_comparator) &&
+				!sieve_comparator_tag_is(carg, &i_octet_comparator) )
+			{
+				sieve_command_validate_error(validator, ctx->command_ctx, 
+					"regex match type only supports i;octet and i;ascii-casemap comparators" );
+				return FALSE;	
+			}
+
+			return TRUE;
+		}
+	
+		carg = sieve_ast_argument_next(carg);
+	}
+
+	return TRUE;
+}
+
 /* Load extension into validator */
 
 static bool ext_regex_validator_load(struct sieve_validator *validator)
diff --git a/src/lib-sieve/plugins/regex/regex-errors.sieve b/src/lib-sieve/plugins/regex/regex-errors.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..10b8b6a65293d8918938123282e28ffde60051a4
--- /dev/null
+++ b/src/lib-sieve/plugins/regex/regex-errors.sieve
@@ -0,0 +1,9 @@
+require "regex";
+require "comparator-i;ascii-numeric";
+
+if address :regex :comparator "i;ascii-numeric" "from" "sirius(\\+.*)?@drunksnipers\\.com" {
+	keep;
+	stop;
+}
+
+discard;
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index 30c7c6ae4fbdeb8e84c887e90484d6b3b854adce..bc41804e8bc97b024bdb09b51f6efd6ed9c8b1c4 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -83,14 +83,17 @@ struct sieve_command_context *sieve_command_context_create
 const char *sieve_command_type_name(const struct sieve_command *command);		
 		
 #define sieve_command_validate_error(validator, context, ...) \
-	sieve_validator_error(validator, context->ast_node, __VA_ARGS__)
+	sieve_validator_error(validator, (context)->ast_node, __VA_ARGS__)
 #define sieve_command_pool(context) \
-	sieve_ast_node_pool(context->ast_node)
+	sieve_ast_node_pool((context)->ast_node)
+
+#define sieve_command_first_argument(context) \
+	sieve_ast_argument_first((context)->ast_node)
 	
 #define sieve_command_is_toplevel(context) \
-	( sieve_ast_node_type(sieve_ast_node_parent(context->ast_node)) == SAT_ROOT )
+	( sieve_ast_node_type(sieve_ast_node_parent((context)->ast_node)) == SAT_ROOT )
 #define sieve_command_is_first(context) \
-	( sieve_ast_node_prev(context->ast_node) == NULL )	
+	( sieve_ast_node_prev((context)->ast_node) == NULL )	
 
 struct sieve_command_context *sieve_command_prev_context	
 	(struct sieve_command_context *context); 
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index 2dfdf6e102887f3aab0e21cf4eda6033e86c0fba..24a2a77aec4f3c0bbd79e333770ab80386117369 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -285,6 +285,13 @@ void sieve_comparators_link_tag
 	sieve_validator_register_tag(validator, cmd_reg, &comparator_tag, id_code); 	
 }
 
+inline bool sieve_comparator_tag_is
+(struct sieve_ast_argument *tag, const struct sieve_comparator *cmp)
+{
+	return (tag->argument == &comparator_tag && 
+		((const struct sieve_comparator *) tag->context) == cmp);
+}
+
 /* Code generation */
 
 static void opr_comparator_emit
diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h
index 70ce48e55a71aa30117322b701e0a58bbd136133..4bd5645118e0586c50c526e8a7876815737001f0 100644
--- a/src/lib-sieve/sieve-comparators.h
+++ b/src/lib-sieve/sieve-comparators.h
@@ -47,13 +47,17 @@ struct sieve_comparator_extension {
 		(unsigned int code);
 };
 
+extern const struct sieve_argument comparator_tag;
+
 void sieve_comparators_link_tag
 	(struct sieve_validator *validator, 
 		struct sieve_command_registration *cmd_reg,	
 		unsigned int id_code);
+inline bool sieve_comparator_tag_is
+(struct sieve_ast_argument *tag, const struct sieve_comparator *cmp);
 
-const struct sieve_comparator i_octet_comparator;
-const struct sieve_comparator i_ascii_casemap_comparator;
+extern const struct sieve_comparator i_octet_comparator;
+extern const struct sieve_comparator i_ascii_casemap_comparator;
 
 void sieve_comparator_register
 	(struct sieve_validator *validator, 
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index 5cb8997a6e7426721cc0b6ebcd5fe0cef1f0786a..715903ff42b24a5df32ffa8845985927d0ae24bb 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -465,7 +465,8 @@ static bool sieve_validate_command_arguments
 static bool sieve_validate_arguments_context
 (struct sieve_validator *validator, struct sieve_command_context *cmd)
 { 
-	struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node);
+	struct sieve_ast_argument *arg = 
+		sieve_command_first_argument(cmd);
 	
 	while ( arg != NULL ) {
 		const struct sieve_argument *argument = arg->argument;