diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index 67ef66bddb552de6dfc0a47bf301950786782691..7af86ff1babec7047b374698a3c401c88c5c7e6e 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -273,13 +273,21 @@ void sieve_extensions_configure(struct sieve_instance *svinst)
 
 	/* Apply sieve_extensions configuration */
 
-	if ( (extensions=sieve_setting_get(svinst, "sieve_extensions")) != NULL )
-		sieve_extensions_set_string(svinst, extensions, FALSE);
+	if ( (extensions=sieve_setting_get
+		(svinst, "sieve_extensions")) != NULL )
+		sieve_extensions_set_string(svinst, extensions, FALSE, FALSE);
 
 	/* Apply sieve_global_extensions configuration */
 
-	if ( (extensions=sieve_setting_get(svinst, "sieve_global_extensions")) != NULL )
-		sieve_extensions_set_string(svinst, extensions, TRUE);
+	if ( (extensions=sieve_setting_get
+		(svinst, "sieve_global_extensions")) != NULL )
+		sieve_extensions_set_string(svinst, extensions, TRUE, FALSE);
+
+	/* Apply sieve_implicit_extensions configuration */
+
+	if ( (extensions=sieve_setting_get
+		(svinst, "sieve_implicit_extensions")) != NULL )
+		sieve_extensions_set_string(svinst, extensions, FALSE, TRUE);
 }
 
 void sieve_extensions_deinit(struct sieve_instance *svinst)
@@ -494,13 +502,23 @@ void sieve_extension_override
 	(*mod_ext)->overridden = TRUE;
 }
 
-int sieve_extensions_get_count(struct sieve_instance *svinst)
+unsigned int sieve_extensions_get_count(struct sieve_instance *svinst)
 {
 	struct sieve_extension_registry *ext_reg = svinst->ext_reg;
 
 	return array_count(&ext_reg->extensions);
 }
 
+const struct sieve_extension *const *
+sieve_extensions_get_all(struct sieve_instance *svinst,
+	unsigned int *count_r)
+{
+	struct sieve_extension_registry *ext_reg = svinst->ext_reg;
+
+	return (const struct sieve_extension *const *)
+		array_get(&ext_reg->extensions, count_r);
+}
+
 const struct sieve_extension *sieve_extension_get_by_id
 (struct sieve_instance *svinst, unsigned int ext_id)
 {
@@ -580,7 +598,6 @@ static void sieve_extension_set_enabled
 {
 	if ( enabled ) {
 		ext->enabled = TRUE;
-		ext->global = FALSE;
 
 		if ( !ext->loaded ) {
 			(void)_sieve_extension_load(ext);
@@ -596,21 +613,27 @@ static void sieve_extension_set_global
 (struct sieve_extension *ext, bool enabled)
 {
 	if ( enabled ) {
-		ext->enabled = TRUE;
+		sieve_extension_set_enabled(ext, TRUE);
 		ext->global = TRUE;
-
-		if ( !ext->loaded ) {
-			(void)_sieve_extension_load(ext);
-		}
-
-		ext->loaded = TRUE;
 	} else {
 		ext->global = FALSE;
 	}
 }
 
+static void sieve_extension_set_implicit
+(struct sieve_extension *ext, bool enabled)
+{
+	if ( enabled ) {
+		sieve_extension_set_enabled(ext, TRUE);
+		ext->implicit = TRUE;
+	} else {
+		ext->implicit = FALSE;
+	}
+}
+
 void sieve_extensions_set_string
-(struct sieve_instance *svinst, const char *ext_string, bool global)
+(struct sieve_instance *svinst, const char *ext_string,
+	bool global, bool implicit)
 {
 	struct sieve_extension_registry *ext_reg = svinst->ext_reg;
 	ARRAY(const struct sieve_extension *) enabled_extensions;
@@ -623,7 +646,7 @@ void sieve_extensions_set_string
 	bool relative = FALSE;
 
 	if ( ext_string == NULL ) {
-		if ( global ) return;
+		if ( global || implicit ) return;
 
 		/* Enable all */
 		exts = array_get_modifiable(&ext_reg->extensions, &ext_count);
@@ -696,6 +719,8 @@ void sieve_extensions_set_string
 			if ( relative ) {
 				if ( global )
 					enabled = exts[i]->global;
+				else if ( implicit )
+					enabled = exts[i]->implicit;
 				else
 					enabled = exts[i]->enabled;
 
@@ -722,6 +747,8 @@ void sieve_extensions_set_string
 			/* Perform actual activation/deactivation */
 			if ( global ) {
 				sieve_extension_set_global(exts[i], enabled);
+			} else if ( implicit ) {
+				sieve_extension_set_implicit(exts[i], enabled);
 			} else {
 				sieve_extension_set_enabled(exts[i], enabled);
 			}
diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h
index 6cf0529c182b98812321d18dad20fc24d420e968..760d44bb39b57758a48392a837d3ed217c717654 100644
--- a/src/lib-sieve/sieve-extensions.h
+++ b/src/lib-sieve/sieve-extensions.h
@@ -95,6 +95,7 @@ struct sieve_extension {
 	unsigned int enabled:1;
 	unsigned int dummy:1;
 	unsigned int global:1;
+	unsigned int implicit:1;
 	unsigned int overridden:1;
 };
 
@@ -142,7 +143,10 @@ void sieve_extension_override
 	(struct sieve_instance *svinst, const char *name,
 		const struct sieve_extension *ext);
 
-int sieve_extensions_get_count(struct sieve_instance *svinst);
+unsigned int sieve_extensions_get_count(struct sieve_instance *svinst);
+const struct sieve_extension *const *
+sieve_extensions_get_all(struct sieve_instance *svinst,
+	unsigned int *count_r);
 
 const struct sieve_extension *sieve_extension_get_by_id
 	(struct sieve_instance *svinst, unsigned int ext_id);
@@ -152,7 +156,8 @@ const struct sieve_extension *sieve_extension_get_by_name
 const char *sieve_extensions_get_string
 	(struct sieve_instance *svinst);
 void sieve_extensions_set_string
-	(struct sieve_instance *svinst, const char *ext_string, bool global);
+	(struct sieve_instance *svinst, const char *ext_string,
+		bool global, bool implicit);
 
 const struct sieve_extension *sieve_get_match_type_extension
 	(struct sieve_instance *svinst);
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index 58dceddb4af68fc26ba291a2cd64fdc2056bbd3c..77ab8440c65780e053db1c824be6b2382ef36f66 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -1372,10 +1372,20 @@ static bool sieve_validate_block
 				&& !valdtr->finished_require &&
 				strcasecmp(cmd_node->identifier, cmd_require.identifier) != 0 ) {
 				const struct sieve_validator_extension_reg *extrs;
+				const struct sieve_extension *const *exts;
 				unsigned int ext_count, i;
 
 				valdtr->finished_require = TRUE;
 
+				/* Load implicit extensions */
+				exts = sieve_extensions_get_all(valdtr->svinst, &ext_count);
+				for (i = 0; i < ext_count; i++) {
+					if ( exts[i]->implicit ) {
+						(void)sieve_validator_extension_load
+							(valdtr, NULL, NULL, exts[i]);
+					}
+				}
+
 				/* Validate all 'require'd extensions */
 				extrs = array_get(&valdtr->extensions, &ext_count);
 				for ( i = 0; i < ext_count; i++ ) {
diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h
index 3a350573e400a3d5b4db4f75a0f80e753ae5e97c..857b7b2ffc4680965f5eba75244a58157eff7145 100644
--- a/src/lib-sieve/sieve-validator.h
+++ b/src/lib-sieve/sieve-validator.h
@@ -138,7 +138,8 @@ struct sieve_validator_extension {
 
 bool sieve_validator_extension_load
 	(struct sieve_validator *valdtr, struct sieve_command *cmd,
-		struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext);
+		struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext)
+	ATTR_NULL(2, 3);
 const struct sieve_extension *sieve_validator_extension_load_by_name
 	(struct sieve_validator *valdtr, struct sieve_command *cmd,
 		struct sieve_ast_argument *ext_arg, const char *ext_name);
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 5d28fd3549d86980d42941ff7e67d67c1e347861..84fbc89d580b1beae0b90fc13ed1214e6ba7833a 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -132,7 +132,7 @@ void sieve_deinit(struct sieve_instance **_svinst)
 void sieve_set_extensions
 (struct sieve_instance *svinst, const char *extensions)
 {
-	sieve_extensions_set_string(svinst, extensions, FALSE);
+	sieve_extensions_set_string(svinst, extensions, FALSE, FALSE);
 }
 
 const char *sieve_get_capabilities