diff --git a/src/lib-sieve/sieve-script-private.h b/src/lib-sieve/sieve-script-private.h
index c876575cdb455031dbedd8a8be224a78e10895a2..19396274dc3aae39cd9f6dc0e965e178fe7fa22d 100644
--- a/src/lib-sieve/sieve-script-private.h
+++ b/src/lib-sieve/sieve-script-private.h
@@ -28,8 +28,9 @@ struct sieve_script_vfuncs {
 				     struct sieve_dumptime_env *denv,
 				     struct sieve_binary_block *sblock,
 				     sieve_size_t *offset);
-	struct sieve_binary *(*binary_load)(struct sieve_script *script,
-					    enum sieve_error *error_code_r);
+	int (*binary_load)(struct sieve_script *script,
+			   struct sieve_binary **sbin_r,
+			   enum sieve_error *error_code_r);
 	int (*binary_save)(struct sieve_script *script,
 			   struct sieve_binary *sbin, bool update,
 			   enum sieve_error *error_code_r);
diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c
index 13796d49f40c763054d9355cc6245897176ea67e..86fdc92f006be3d4a713930f7ddffd43cfea1c54 100644
--- a/src/lib-sieve/sieve-script.c
+++ b/src/lib-sieve/sieve-script.c
@@ -516,16 +516,28 @@ bool sieve_script_binary_dump_metadata(struct sieve_script *script,
 	return result;
 }
 
-struct sieve_binary *
-sieve_script_binary_load(struct sieve_script *script,
-			 enum sieve_error *error_code_r)
+int sieve_script_binary_load(struct sieve_script *script,
+			     struct sieve_binary **sbin_r,
+			     enum sieve_error *error_code_r)
 {
+	enum sieve_error error_code;
+	int ret;
+
+	*sbin_r = NULL;
+	if (error_code_r != NULL)
+		*error_code_r = SIEVE_ERROR_NONE;
+	else
+		error_code_r = &error_code;
+
 	if (script->v.binary_load == NULL) {
 		*error_code_r = SIEVE_ERROR_NOT_POSSIBLE;
-		return NULL;
+		return -1;
 	}
 
-	return script->v.binary_load(script, error_code_r);
+	ret = script->v.binary_load(script, sbin_r, error_code_r);
+	i_assert(ret <= 0);
+	i_assert(ret < 0 || *sbin_r != NULL);
+	return ret;
 }
 
 int sieve_script_binary_save(struct sieve_script *script,
diff --git a/src/lib-sieve/sieve-script.h b/src/lib-sieve/sieve-script.h
index c861b5ea4d08c77a96130ab8657937171838ed5e..3cc218758ac732962f2001b808830ab867966458 100644
--- a/src/lib-sieve/sieve-script.h
+++ b/src/lib-sieve/sieve-script.h
@@ -77,9 +77,9 @@ bool sieve_script_binary_dump_metadata(struct sieve_script *script,
 				       struct sieve_binary_block *sblock,
 				       sieve_size_t *offset) ATTR_NULL(1);
 
-struct sieve_binary *
-sieve_script_binary_load(struct sieve_script *script,
-			 enum sieve_error *error_code_r);
+int sieve_script_binary_load(struct sieve_script *script,
+			     struct sieve_binary **sbin_r,
+			     enum sieve_error *error_code_r);
 int sieve_script_binary_save(struct sieve_script *script,
 			     struct sieve_binary *sbin, bool update,
 			     enum sieve_error *error_code_r);
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 1e8cd09cb5f259ae01c109a39edf95bf1f5f2299..db1b27798e0f7ea3d07bf5c5131b1737d748497b 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -403,8 +403,7 @@ sieve_open_script_real(struct sieve_script *script,
 	sieve_resource_usage_init(&rusage);
 
 	/* Try to open the matching binary */
-	sbin = sieve_script_binary_load(script, error_code_r);
-	if (sbin != NULL) {
+	if (sieve_script_binary_load(script, &sbin, error_code_r) == 0) {
 		sieve_binary_get_resource_usage(sbin, &rusage);
 
 		/* Ok, it exists; now let's see if it is up to date */
diff --git a/src/lib-sieve/storage/dict/sieve-dict-script.c b/src/lib-sieve/storage/dict/sieve-dict-script.c
index 9ea88710c5b12b518adc39ce997d4ad6345b4664..91edf285e038ff6c7d75a28d535ff97ea484da92 100644
--- a/src/lib-sieve/storage/dict/sieve-dict-script.c
+++ b/src/lib-sieve/storage/dict/sieve-dict-script.c
@@ -224,21 +224,19 @@ sieve_dict_script_get_binpath(struct sieve_dict_script *dscript)
 	return dscript->binpath;
 }
 
-static struct sieve_binary *
+static int
 sieve_dict_script_binary_load(struct sieve_script *script,
+			      struct sieve_binary **sbin_r,
 			      enum sieve_error *error_code_r)
 {
 	struct sieve_dict_script *dscript =
 		container_of(script, struct sieve_dict_script, script);
-	struct sieve_binary *sbin;
 
 	if (sieve_dict_script_get_binpath(dscript) == NULL)
-		return NULL;
+		return -1;
 
-	if (sieve_binary_open(script->storage->svinst, dscript->binpath,
-			      script, &sbin, error_code_r) < 0)
-		return NULL;
-	return sbin;
+	return sieve_binary_open(script->storage->svinst, dscript->binpath,
+				 script, sbin_r, error_code_r);
 }
 
 static int
diff --git a/src/lib-sieve/storage/file/sieve-file-script.c b/src/lib-sieve/storage/file/sieve-file-script.c
index 910cb7354b40778ca1b40cce4ae75e87fe9cdd87..d48df77353b43970d12f37dc93c184887c8be70f 100644
--- a/src/lib-sieve/storage/file/sieve-file-script.c
+++ b/src/lib-sieve/storage/file/sieve-file-script.c
@@ -531,19 +531,17 @@ sieve_file_script_binary_read_metadata(struct sieve_script *script,
 	return 1;
 }
 
-static struct sieve_binary *
+static int
 sieve_file_script_binary_load(struct sieve_script *script,
+			      struct sieve_binary **sbin_r,
 			      enum sieve_error *error_code_r)
 {
 	struct sieve_file_script *fscript =
 		container_of(script, struct sieve_file_script, script);
 	struct sieve_instance *svinst = script->storage->svinst;
-	struct sieve_binary *sbin;
 
-	if (sieve_binary_open(svinst, fscript->binpath, script,
-			      &sbin, error_code_r) < 0)
-		return NULL;
-	return sbin;
+	return sieve_binary_open(svinst, fscript->binpath, script,
+				 sbin_r, error_code_r);
 }
 
 static int
diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-script.c b/src/lib-sieve/storage/ldap/sieve-ldap-script.c
index 027e0f21ca746e53455f0d890bf16f657c30207b..0a27adc831e91a974c309657f31ef7decb7a99e0 100644
--- a/src/lib-sieve/storage/ldap/sieve-ldap-script.c
+++ b/src/lib-sieve/storage/ldap/sieve-ldap-script.c
@@ -246,22 +246,20 @@ sieve_ldap_script_get_binpath(struct sieve_ldap_script *lscript)
 	return lscript->binpath;
 }
 
-static struct sieve_binary *
+static int
 sieve_ldap_script_binary_load(struct sieve_script *script,
+			      struct sieve_binary **sbin_r,
 			      enum sieve_error *error_code_r)
 {
 	struct sieve_storage *storage = script->storage;
 	struct sieve_ldap_script *lscript =
 		container_of(script, struct sieve_ldap_script, script);
-	struct sieve_binary *sbin;
 
 	if (sieve_ldap_script_get_binpath(lscript) == NULL)
-		return NULL;
+		return -1;
 
-	if (sieve_binary_open(storage->svinst, lscript->binpath, script,
-			      &sbin, error_code_r) < 0)
-		return NULL;
-	return sbin;
+	return sieve_binary_open(storage->svinst, lscript->binpath, script,
+				 sbin_r, error_code_r);
 }
 
 static int