diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index b50acd36ae5876f5fe5abf8182ecfdcbacba8b18..b40fda9cd3dceb6b79f04d658c08ab375fa03e77 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -708,8 +708,8 @@ int ext_include_execute_include
 			 * (first sub-interpreter)
 			 */
 			subinterp = sieve_interpreter_create_for_block
-				(included->block, included->script, renv->msgdata, renv->scriptenv,
-					ehandler, rtflags);
+				(included->block, included->script, renv->interp,
+					renv->msgdata, renv->scriptenv, ehandler, rtflags);
 
 			if ( subinterp != NULL ) {
 				curctx = ext_include_interpreter_context_init_child
@@ -767,7 +767,8 @@ int ext_include_execute_include
 
 							/* Create sub-interpreter */
 							subinterp = sieve_interpreter_create_for_block
-								(curctx->include->block, curctx->include->script, renv->msgdata,
+								(curctx->include->block, curctx->include->script,
+									curctx->interp, renv->msgdata,
 									renv->scriptenv, ehandler, rtflags);
 
 							if ( subinterp != NULL ) {
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index 5e332156de32e7d6ecf86457d09393ddcf86867d..7c87e1e5eb88e73b7ab944ecd207f65abfa2e328 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -71,6 +71,7 @@ struct sieve_interpreter {
 	/* Loop stack */
 	ARRAY(struct sieve_interpreter_loop) loop_stack;
 	sieve_size_t loop_limit;
+	unsigned int parent_loop_level;
 
 	/* Runtime environment */
 	struct sieve_runtime_env runenv;
@@ -85,10 +86,15 @@ struct sieve_interpreter {
 };
 
 static struct sieve_interpreter *_sieve_interpreter_create
-(struct sieve_binary *sbin, struct sieve_binary_block *sblock,
-	struct sieve_script *script, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
+(struct sieve_binary *sbin,
+	struct sieve_binary_block *sblock,
+	struct sieve_script *script,
+	struct sieve_interpreter *parent,
+	const struct sieve_message_data *msgdata,
+	const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler,
 	enum sieve_runtime_flags flags)
+	ATTR_NULL(3, 4)
 {
 	unsigned int i, ext_count;
 	struct sieve_interpreter *interp;
@@ -143,6 +149,12 @@ static struct sieve_interpreter *_sieve_interpreter_create
 
 	p_array_init(&interp->extensions, pool, sieve_extensions_get_count(svinst));
 
+	interp->parent_loop_level = 0;
+	if ( parent != NULL && array_is_created(&parent->loop_stack) ) {
+		interp->parent_loop_level = parent->parent_loop_level +
+			array_count(&parent->loop_stack);
+	}
+
 	/* Pre-load core language features implemented as 'extensions' */
 	ext_preloaded = sieve_extensions_get_preloaded(svinst, &ext_count);
 	for ( i = 0; i < ext_count; i++ ) {
@@ -211,8 +223,11 @@ static struct sieve_interpreter *_sieve_interpreter_create
 }
 
 struct sieve_interpreter *sieve_interpreter_create
-(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
+(struct sieve_binary *sbin,
+	struct sieve_interpreter *parent,
+	const struct sieve_message_data *msgdata,
+	const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler,
 	enum sieve_runtime_flags flags)
 {
 	struct sieve_binary_block *sblock;
@@ -221,20 +236,24 @@ struct sieve_interpreter *sieve_interpreter_create
 		== NULL )
 		return NULL;
 
- 	return _sieve_interpreter_create
-		(sbin, sblock, NULL, msgdata, senv, ehandler, flags);
+ 	return _sieve_interpreter_create(sbin, sblock, NULL,
+		parent, msgdata, senv, ehandler, flags);
 }
 
 struct sieve_interpreter *sieve_interpreter_create_for_block
-(struct sieve_binary_block *sblock, struct sieve_script *script,
-	const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
-	struct sieve_error_handler *ehandler, enum sieve_runtime_flags flags)
+(struct sieve_binary_block *sblock,
+	struct sieve_script *script,
+	struct sieve_interpreter *parent,
+	const struct sieve_message_data *msgdata,
+	const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler,
+	enum sieve_runtime_flags flags)
 {
 	if ( sblock == NULL ) return NULL;
 
  	return _sieve_interpreter_create
-		(sieve_binary_block_get_binary(sblock), sblock, script, msgdata, senv,
-			ehandler, flags);
+		(sieve_binary_block_get_binary(sblock), sblock, script,
+			parent, msgdata, senv, ehandler, flags);
 }
 
 void sieve_interpreter_free(struct sieve_interpreter **_interp)
@@ -513,7 +532,7 @@ int sieve_interpreter_loop_start
 
 	if ( !array_is_created(&interp->loop_stack) )
 		p_array_init(&interp->loop_stack, interp->pool, 8);
-	else if ( array_count(&interp->loop_stack)
+	if ( (interp->parent_loop_level + array_count(&interp->loop_stack))
 		>= SIEVE_MAX_LOOP_DEPTH ) {
 		/* Should normally be caught at compile time */
 		sieve_runtime_error(renv, NULL,
diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h
index bace3155f2b482108dfbd8f9df1a77aea9c8065e..f2d96380b14bac2a0fdb13d0f63b1ec103ae5064 100644
--- a/src/lib-sieve/sieve-interpreter.h
+++ b/src/lib-sieve/sieve-interpreter.h
@@ -16,14 +16,22 @@
  */
 
 struct sieve_interpreter *sieve_interpreter_create
-	(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-		enum sieve_runtime_flags flags);
+	(struct sieve_binary *sbin,
+		struct sieve_interpreter *parent,
+		const struct sieve_message_data *msgdata,
+		const struct sieve_script_env *senv,
+		struct sieve_error_handler *ehandler,
+		enum sieve_runtime_flags flags)
+	ATTR_NULL(2);
 struct sieve_interpreter *sieve_interpreter_create_for_block
-	(struct sieve_binary_block *sblock, struct sieve_script *script,
+	(struct sieve_binary_block *sblock,
+		struct sieve_script *script,
+		struct sieve_interpreter *parent,
 		const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
+		const struct sieve_script_env *senv,
+		struct sieve_error_handler *ehandler,
 		enum sieve_runtime_flags flags);
+	ATTR_NULL(3);
 void sieve_interpreter_free(struct sieve_interpreter **_interp);
 
 /*
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index c5a4fe9773c4886a694bc8791225e86a53ef8fe8..de30e186210711bbbd00c47a1542ad495145e824 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -323,8 +323,8 @@ static int sieve_run
 	int ret = 0;
 
 	/* Create the interpreter */
-	if ( (interp=sieve_interpreter_create(sbin, msgdata, senv, ehandler, flags))
-		== NULL )
+	if ( (interp=sieve_interpreter_create
+		(sbin, NULL, msgdata, senv, ehandler, flags)) == NULL )
 		return SIEVE_EXEC_BIN_CORRUPT;
 
 	/* Reset execution status */
diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c
index f653b2014ae84dd7d1bb0330e022b8faefff9bcc..095fb3067bac60616b8d9361bb1f72dcb02e623c 100644
--- a/src/testsuite/testsuite-script.c
+++ b/src/testsuite/testsuite-script.c
@@ -122,8 +122,8 @@ bool testsuite_script_run(const struct sieve_runtime_env *renv)
 	result = testsuite_result_get();
 
 	/* Execute the script */
-	interp=sieve_interpreter_create(ictx->compiled_script, renv->msgdata,
-		&scriptenv, testsuite_log_ehandler, 0);
+	interp=sieve_interpreter_create(ictx->compiled_script,
+		NULL, renv->msgdata, &scriptenv, testsuite_log_ehandler, 0);
 
 	if ( interp == NULL )
 		return SIEVE_EXEC_BIN_CORRUPT;
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 38786b8cf90349a62b7b60e7b31ce2be7d8ef650..fd5d0f563907c979f50fb04ace75017cdbe27542 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -65,7 +65,7 @@ static int testsuite_run
 
 	/* Create the interpreter */
 	if ( (interp=sieve_interpreter_create
-		(sbin, msgdata, senv, ehandler, 0)) == NULL )
+		(sbin, NULL, msgdata, senv, ehandler, 0)) == NULL )
 		return SIEVE_EXEC_BIN_CORRUPT;
 
 	/* Run the interpreter */
diff --git a/tests/extensions/mime/errors.svtest b/tests/extensions/mime/errors.svtest
index 2a183b5e4bc0db8a5242e05a794be019cdb7a897..31235264e06436de0c95d4243297b625930c5d0c 100644
--- a/tests/extensions/mime/errors.svtest
+++ b/tests/extensions/mime/errors.svtest
@@ -3,7 +3,7 @@ require "vnd.dovecot.testsuite";
 require "relational";
 require "comparator-i;ascii-numeric";
 
-test "Foreverypart command" {
+/*test "Foreverypart command" {
 	if test_script_compile "errors/foreverypart.sieve" {
 		test_fail "compile should have failed";
 	}
@@ -61,4 +61,15 @@ test "Limits" {
 	if test_error :count "ne" :comparator "i;ascii-numeric" "2" {
 		test_fail "incorrect number of compile errors reported";
 	}
+}*/
+
+test "Limits - include" {
+	if not test_script_compile "errors/limits-include.sieve" {
+		test_fail "script compile failed";
+	}
+
+	if test_script_run {
+		test_fail "script run should have failed";
+	}
 }
+
diff --git a/tests/extensions/mime/errors/limits-include.sieve b/tests/extensions/mime/errors/limits-include.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..ef924563c47d7af2ad6e48642221e6bb634aa161
--- /dev/null
+++ b/tests/extensions/mime/errors/limits-include.sieve
@@ -0,0 +1,6 @@
+require "foreverypart";
+require "include";
+
+foreverypart :name "frop" {
+	include "include-loop-2";
+}
diff --git a/tests/extensions/mime/included/include-loop-2.sieve b/tests/extensions/mime/included/include-loop-2.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..80c5884540e5d3404a68f47ffae1ff8a1049c2eb
--- /dev/null
+++ b/tests/extensions/mime/included/include-loop-2.sieve
@@ -0,0 +1,6 @@
+require "foreverypart";
+require "include";
+
+foreverypart :name "friep" {
+	include "include-loop-3";
+}
diff --git a/tests/extensions/mime/included/include-loop-3.sieve b/tests/extensions/mime/included/include-loop-3.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..228a8bc34509b9d66d8ee776d3197d2f52b805c4
--- /dev/null
+++ b/tests/extensions/mime/included/include-loop-3.sieve
@@ -0,0 +1,6 @@
+require "foreverypart";
+require "include";
+
+foreverypart :name "frml" {
+	include "include-loop-4";
+}
diff --git a/tests/extensions/mime/included/include-loop-4.sieve b/tests/extensions/mime/included/include-loop-4.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..00dad847dcd1093004de3c512a47a79a444955bd
--- /dev/null
+++ b/tests/extensions/mime/included/include-loop-4.sieve
@@ -0,0 +1,6 @@
+require "foreverypart";
+require "include";
+
+foreverypart {
+	include "include-loop-5";
+}
diff --git a/tests/extensions/mime/included/include-loop-5.sieve b/tests/extensions/mime/included/include-loop-5.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..e22b21cad1063ef3d7e8e91253d5699455f80278
--- /dev/null
+++ b/tests/extensions/mime/included/include-loop-5.sieve
@@ -0,0 +1,9 @@
+require "foreverypart";
+require "include";
+require "mime";
+
+foreverypart {
+	if header :mime :subtype "content-type" "plain" {
+		break;
+	}
+}