diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 8a3f4408668bfb5b799184c52efc531ee719f127..3442dbd4462f613752f20edef1d15297f816071a 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -251,16 +251,17 @@ sieve_generate(struct sieve_ast *ast, struct sieve_error_handler *ehandler,
  * Sieve compilation
  */
 
-struct sieve_binary *
-sieve_compile_script(struct sieve_script *script,
-		     struct sieve_error_handler *ehandler,
-		     enum sieve_compile_flags flags,
-		     enum sieve_error *error_code_r)
+int sieve_compile_script(struct sieve_script *script,
+			 struct sieve_error_handler *ehandler,
+			 enum sieve_compile_flags flags,
+			 struct sieve_binary **sbin_r,
+			 enum sieve_error *error_code_r)
 {
 	struct sieve_ast *ast;
 	struct sieve_binary *sbin;
 	enum sieve_error error_code;
 
+	*sbin_r = NULL;
 	if (error_code_r != NULL)
 		*error_code_r = SIEVE_ERROR_NONE;
 	else
@@ -280,7 +281,7 @@ sieve_compile_script(struct sieve_script *script,
 			sieve_error(ehandler, sieve_script_name(script),
 				    "parse failed");
 		}
-		return NULL;
+		return -1;
 	}
 
 	/* Validate */
@@ -289,7 +290,7 @@ sieve_compile_script(struct sieve_script *script,
 			    "validation failed");
 
  		sieve_ast_unref(&ast);
-		return NULL;
+		return -1;
  	}
 
 	/* Generate */
@@ -298,12 +299,13 @@ sieve_compile_script(struct sieve_script *script,
 		sieve_error(ehandler, sieve_script_name(script),
 			    "code generation failed");
 		sieve_ast_unref(&ast);
-		return NULL;
+		return -1;
 	}
 
 	/* Cleanup */
 	sieve_ast_unref(&ast);
-	return sbin;
+	*sbin_r = sbin;
+	return 0;
 }
 
 int sieve_compile(struct sieve_instance *svinst, const char *script_location,
@@ -312,7 +314,6 @@ int sieve_compile(struct sieve_instance *svinst, const char *script_location,
 		  enum sieve_error *error_code_r)
 {
 	struct sieve_script *script;
-	struct sieve_binary *sbin;
 	enum sieve_error error_code;
 
 	*sbin_r = NULL;
@@ -334,8 +335,8 @@ int sieve_compile(struct sieve_instance *svinst, const char *script_location,
 		return -1;
 	}
 
-	sbin = sieve_compile_script(script, ehandler, flags, error_code_r);
-	if (sbin == NULL) {
+	if (sieve_compile_script(script, ehandler, flags,
+				 sbin_r, error_code_r) < 0) {
 		sieve_script_unref(&script);
 		return -1;
 	}
@@ -343,7 +344,6 @@ int sieve_compile(struct sieve_instance *svinst, const char *script_location,
 	e_debug(svinst->event, "Script '%s' from %s successfully compiled",
 		sieve_script_name(script), sieve_script_location(script));
 
-	*sbin_r = sbin;
 	sieve_script_unref(&script);
 	return 0;
 }
@@ -431,9 +431,8 @@ sieve_open_script_real(struct sieve_script *script,
 			"Script binary %s successfully loaded",
 			sieve_binary_path(sbin));
 	} else {
-		sbin = sieve_compile_script(script, ehandler, flags,
-					    error_code_r);
-		if (sbin == NULL)
+		if (sieve_compile_script(script, ehandler, flags,
+					 &sbin, error_code_r) < 0)
 			return NULL;
 
 		e_debug(svinst->event,
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index df838958bcb0246788cba340f9948b36f466e029..e207d9d1329d7e88a3d02618952c5699deaf8a8a 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -38,11 +38,11 @@ void sieve_set_extensions(struct sieve_instance *svinst,
 
 /* Compile a Sieve script from a Sieve script object. Returns Sieve binary upon
    success and NULL upon failure. */
-struct sieve_binary *
-sieve_compile_script(struct sieve_script *script,
-		     struct sieve_error_handler *ehandler,
-		     enum sieve_compile_flags flags,
-		     enum sieve_error *error_code_r);
+int sieve_compile_script(struct sieve_script *script,
+			 struct sieve_error_handler *ehandler,
+			 enum sieve_compile_flags flags,
+			 struct sieve_binary **sbin_r,
+			 enum sieve_error *error_code_r);
 
 /* Compile a Sieve script from a Sieve script location string. Returns Sieve
    binary upon success and NULL upon failure. The provided script_name is used
diff --git a/src/managesieve/cmd-putscript.c b/src/managesieve/cmd-putscript.c
index fe2c2a9c3ea48542eb18e0362f0b76d60d47094f..4b25a15a9045bdb8ecc30c58b02713f8f3c1a843 100644
--- a/src/managesieve/cmd-putscript.c
+++ b/src/managesieve/cmd-putscript.c
@@ -196,8 +196,8 @@ cmd_putscript_finish_script(struct cmd_putscript_context *ctx,
 		client->set->managesieve_max_compile_errors);
 
 	/* Compile */
-	sbin = sieve_compile_script(script, ehandler, cpflags, &error_code);
-	if (sbin == NULL) {
+	if (sieve_compile_script(script, ehandler, cpflags,
+				 &sbin, &error_code) < 0) {
 		const char *errormsg = NULL, *action;
 
 		if (error_code != SIEVE_ERROR_NOT_VALID) {
diff --git a/src/managesieve/cmd-setactive.c b/src/managesieve/cmd-setactive.c
index e0da44a4466d0e464f4e68265f2690db8259118e..49fd9db67f811f216fdadea74ccbd85db3cd1e3f 100644
--- a/src/managesieve/cmd-setactive.c
+++ b/src/managesieve/cmd-setactive.c
@@ -50,9 +50,8 @@ cmd_setactive_activate(struct client_command_context *cmd,
 			client->set->managesieve_max_compile_errors);
 
 		/* Compile */
-		sbin = sieve_compile_script(script, ehandler, cpflags,
-					    &error_code);
-		if (sbin == NULL) {
+		if (sieve_compile_script(script, ehandler, cpflags,
+					 &sbin, &error_code) < 0) {
 			if (error_code != SIEVE_ERROR_NOT_VALID) {
 				errormsg = sieve_script_get_last_error(
 					script, &error_code);
diff --git a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c
index 3abe25d7b2d57ee039253723074a79d7783769e1..a87a9465e35daf3e0d288495ca9a2796d338cfc6 100644
--- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c
+++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-activate.c
@@ -48,9 +48,8 @@ static int cmd_sieve_activate_run(struct doveadm_sieve_cmd_context *_ctx)
 
 		/* Compile */
 		ehandler = sieve_master_ehandler_create(ctx->ctx.svinst, 0);
-		sbin = sieve_compile_script(script, ehandler, cpflags,
-					    &error_code);
-		if (sbin == NULL) {
+		if (sieve_compile_script(script, ehandler, cpflags,
+					 &sbin, &error_code) < 0) {
 			doveadm_sieve_cmd_failed_error(_ctx, error_code);
 			ret = -1;
 		} else {
diff --git a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c
index c4529fd4d35efa174db17dc167a57deb356c92df..3153e3695eaa7fd98ea4f24f2b5e1ccff9853425 100644
--- a/src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c
+++ b/src/plugins/doveadm-sieve/doveadm-sieve-cmd-put.c
@@ -96,9 +96,8 @@ static int cmd_sieve_put_run(struct doveadm_sieve_cmd_context *_ctx)
 			/* Compile */
 			ehandler = sieve_master_ehandler_create(
 				ctx->ctx.svinst, 0);
-			sbin = sieve_compile_script(script, ehandler, cpflags,
-						    &error_code);
-			if (sbin == NULL) {
+			if (sieve_compile_script(script, ehandler, cpflags,
+						 &sbin, &error_code) < 0) {
 				doveadm_sieve_cmd_failed_error(
 					_ctx, error_code);
 				ret = -1;
diff --git a/src/plugins/imap-filter-sieve/imap-filter-sieve.c b/src/plugins/imap-filter-sieve/imap-filter-sieve.c
index 47ba7d9764648be824251f4f99feedf2682a7914..3b9cd5425e8b850c3cb71c620a09ee977b5fee31 100644
--- a/src/plugins/imap-filter-sieve/imap-filter-sieve.c
+++ b/src/plugins/imap-filter-sieve/imap-filter-sieve.c
@@ -382,8 +382,9 @@ imap_sieve_filter_open_script(struct imap_filter_sieve_context *sctx,
 
 	/* Load or compile the sieve script */
 	if (recompile) {
-		sbin = sieve_compile_script(script, ehandler, cpflags,
-					    error_code_r);
+		if (sieve_compile_script(script, ehandler, cpflags,
+					 &sbin, error_code_r) < 0)
+			sbin = NULL;
 	} else {
 		sbin = sieve_open_script(script, ehandler, cpflags,
 					 error_code_r);
diff --git a/src/plugins/imapsieve/imap-sieve.c b/src/plugins/imapsieve/imap-sieve.c
index 9e624c180412322f021e25e84ec9bf147e2eb977..82e4582baa23a207c44b2dff9f682cc56c36350c 100644
--- a/src/plugins/imapsieve/imap-sieve.c
+++ b/src/plugins/imapsieve/imap-sieve.c
@@ -590,8 +590,9 @@ imap_sieve_run_open_script(struct imap_sieve_run *isrun,
 
 	/* Load or compile the sieve script */
 	if (recompile) {
-		sbin = sieve_compile_script(script, ehandler, cpflags,
-					    error_code_r);
+		if (sieve_compile_script(script, ehandler, cpflags,
+					 &sbin, error_code_r) < 0)
+			sbin = NULL;
 	} else {
 		sbin = sieve_open_script(script, ehandler, cpflags,
 					 error_code_r);
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 7e7a3bf4363661776ac3e5c3706c8dbd37c094dc..569b84b48ddb5802f765193b913d77289c58e4ae 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -369,8 +369,10 @@ sieve_binary *lda_sieve_open(struct lda_sieve_run_context *srctx,
 	sieve_error_handler_reset(ehandler);
 
 	if (recompile) {
-		sbin = sieve_compile_script(script, ehandler, cpflags,
-					    error_code_r);
+		if (sieve_compile_script(script, ehandler, cpflags,
+					 &sbin, error_code_r) < 0)
+			sbin = NULL;
+
 	} else {
 		sbin = sieve_open_script(script, ehandler, cpflags,
 					 error_code_r);