diff --git a/src/lib-sieve/plugins/editheader/cmd-addheader.c b/src/lib-sieve/plugins/editheader/cmd-addheader.c
index 6481edd94d54642b7ba7799ec7a5f74d52d07715..c76e0e239960dd728ab33a3f8fb12d72deb7fc47 100644
--- a/src/lib-sieve/plugins/editheader/cmd-addheader.c
+++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c
@@ -83,6 +83,24 @@ const struct sieve_operation_def addheader_operation = {
 	cmd_addheader_operation_execute
 };
 
+/*
+ * Utility
+ */
+
+static bool _str_contains_nul(const string_t *str)
+{
+	const unsigned char *p, *pend;
+
+	p = str_data(str);
+	pend = p + str_len(str);
+	while (p < pend) {
+		if (*p == '\0')
+			return TRUE;
+		p++;
+	}
+	return FALSE;
+}
+
 /*
  * Validation
  */
@@ -134,12 +152,18 @@ static bool cmd_addheader_validate
 	if ( sieve_argument_is_string_literal(arg) ) {
 		string_t *fvalue = sieve_ast_argument_str(arg);
 
+		if ( _str_contains_nul(fvalue) ) {
+			sieve_argument_validate_error(valdtr, arg,
+				"addheader command: specified value `%s' is invalid "
+				"(contains NUL character)",	str_sanitize(str_c(fvalue), 80));
+			return FALSE;
+		}	
+
 		if ( !rfc2822_header_field_body_verify
 			(str_c(fvalue), str_len(fvalue), TRUE, TRUE) ) {
-			sieve_argument_validate_error(valdtr, arg,
+			sieve_argument_validate_warning(valdtr, arg,
 				"addheader command: specified value `%s' is invalid",
 				str_sanitize(str_c(fvalue), 80));
-			return FALSE;
 		}
 
 		if ( ext_editheader_header_too_large(cmd->ext, str_len(fvalue)) ) {
@@ -281,10 +305,9 @@ static int cmd_addheader_operation_execute
 		return SIEVE_EXEC_OK;
 	}
 
-	if ( !rfc2822_header_field_body_verify
-		(str_c(value), str_len(value), TRUE, TRUE) ) {
+	if ( _str_contains_nul(value) ) {
 		sieve_runtime_error(renv, NULL, "addheader action: "
-			"specified value `%s' is invalid",
+			"specified value `%s' is invalid (contains NUL character)",
 			str_sanitize(str_c(value), 80));
 		return SIEVE_EXEC_FAILURE;
 	}
@@ -304,6 +327,8 @@ static int cmd_addheader_operation_execute
 		str_sanitize(str_c(field_name), 80), str_sanitize(str_c(value), 80));
 
 	edmail = sieve_message_edit(renv->msgctx);
-	edit_mail_header_add(edmail, rfc2822_header_field_name_sanitize(str_c(field_name)), str_c(value), last);
+	edit_mail_header_add(edmail,
+		rfc2822_header_field_name_sanitize(str_c(field_name)),
+		str_c(value), last);
 	return SIEVE_EXEC_OK;
 }
diff --git a/tests/extensions/editheader/addheader.svtest b/tests/extensions/editheader/addheader.svtest
index 1ce7d44471ba784eb96ffc8900f740ece1929f53..944d66fc044d2b7ef080d9b0d467333e68839eba 100644
--- a/tests/extensions/editheader/addheader.svtest
+++ b/tests/extensions/editheader/addheader.svtest
@@ -1,4 +1,5 @@
 require "vnd.dovecot.testsuite";
+require "encoded-character";
 require "variables";
 require "fileinto";
 require "mailbox";
@@ -524,4 +525,72 @@ test "Addheader - implicit keep" {
 	}
 }
 
+test_set "message" "${message}";
+test "Addheader - UTF 8" {
+	if size :over 76 {
+		test_fail "original message is longer than 76 bytes?!";
+	}
+
+	addheader "X-Some-Header" "Это тест!";
+	fileinto :create "folder4";
+
+	if not test_result_execute {
+		test_fail "failed to execute result";
+	}
+
+	if not test_message :folder "folder4" 0 {
+		test_fail "message not stored";
+	}
+
+	if not exists "x-some-header" {
+		test_fail "header not added to stored message";
+	}
+
+	if not header :is "x-some-header" "Это тест!" {
+		if header :matches "x-some-header" "*" {}
+		test_fail "Bel character not retained: `${0}`";
+	}
+
+	if not body :matches "Frop!*" {
+		test_fail "body not retained in stored mail";
+	}
+}
+
+test_result_reset;
+
+test_set "message" "${message}";
+test "Addheader - devious characters" {
+	if size :over 76 {
+		test_fail "original message is longer than 76 bytes?!";
+	}
+
+	addheader "X-Some-Header" "Ring my ${hex:07}!";
+	fileinto :create "folder5";
+
+	if not test_result_execute {
+		test_fail "failed to execute result";
+	}
+
+	if not test_message :folder "folder5" 0 {
+		test_fail "message not stored";
+	}
+
+	if not exists "x-some-header" {
+		test_fail "header not added to stored message";
+	}
+
+	if header :is "x-some-header" "Ring my !" {
+		if header :matches "x-some-header" "*" {}
+		test_fail "Bel character not retained: `${0}`";
+	}
+
+	if not header :is "x-some-header" "Ring my ${hex:07}!" {
+		if header :matches "x-some-header" "*" {}
+		test_fail "Incorrect header value: `${0}`";
+	}
+
+	if not body :matches "Frop!*" {
+		test_fail "body not retained in stored mail";
+	}
+}
 
diff --git a/tests/extensions/editheader/errors.svtest b/tests/extensions/editheader/errors.svtest
index b7d4136c54a7dea00e05b9f4cf50f125694d300a..1d1f24d57d81c649b5bd01a5d004fb7005785a02 100644
--- a/tests/extensions/editheader/errors.svtest
+++ b/tests/extensions/editheader/errors.svtest
@@ -1,6 +1,7 @@
 require "vnd.dovecot.testsuite";
 require "comparator-i;ascii-numeric";
 require "relational";
+require "variables";
 
 require "editheader";
 
@@ -53,16 +54,12 @@ test "Invalid field value" {
 		test_fail "compile should have failed";
 	}
 
-	if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
+	if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
 		test_fail "wrong number of errors reported";
 	}
 
-	if not test_error :index 1 :matches "*value*Yeah!?*invalid*" {
-		test_fail "wrong error reported (1)";
-	}
-
-	if not test_error :index 2 :matches "*value*Woah!*invalid*" {
-		test_fail "wrong error reported (2)";
+	if not test_error :index 1 :matches "*value*Woah*invalid*" {
+		test_fail "wrong error reported (1): ${0}";
 	}
 }
 
diff --git a/tests/extensions/editheader/errors/field-value.sieve b/tests/extensions/editheader/errors/field-value.sieve
index 7dc3fd8ffbf6d253ad0ac2e8a59700a797bd28d7..c9f4eabd44a419032bb90f29956b44fe539b5edf 100644
--- a/tests/extensions/editheader/errors/field-value.sieve
+++ b/tests/extensions/editheader/errors/field-value.sieve
@@ -8,8 +8,8 @@ addheader "X-field" "Frop";
 addheader "X-field" "Frop
 Frml";
 
-# Invalid 'BELL'
-addheader "X-field" "Yeah!${hex:07}";
+# Invalid 'BELL'; but not an error
+addheader "X-field" "Yeah${hex:07}!";
 
 # Invalid 'NUL'
-addheader "X-field" "Woah!${hex:00}";
+addheader "X-field" "Woah${hex:00}!";