diff --git a/src/libknot/util/error.h b/src/libknot/util/error.h
index 46c19d40210f6d7b5c6420986bc93318731d4a8f..db726f04145f22d78fe53f4b32c25781dadf8ecb 100644
--- a/src/libknot/util/error.h
+++ b/src/libknot/util/error.h
@@ -94,6 +94,7 @@ enum knot_error {
 	ZSCANNER_EBAD_GATEWAY,
 	ZSCANNER_EBAD_APL,
 	ZSCANNER_EBAD_RDATA,
+	ZSCANNER_EBAD_HEX_RDATA,
 	ZSCANNER_EBAD_HEX_CHAR,
 	ZSCANNER_EBAD_BASE64_CHAR,
 	ZSCANNER_EBAD_BASE32HEX_CHAR,
@@ -105,6 +106,7 @@ enum knot_error {
 	ZSCANNER_EBAD_TIME,
 	ZSCANNER_EBAD_BITMAP,
 	ZSCANNER_ETEXT_OVERFLOW,
+	ZSCANNER_EBAD_TEXT,
 	ZSCANNER_EBAD_DIRECTIVE,
 	ZSCANNER_EBAD_TTL,
 	ZSCANNER_EBAD_ORIGIN,
diff --git a/src/libknot/util/libknot_error.c b/src/libknot/util/libknot_error.c
index 8acecb77b859bd04e41ef61ce96831542242c47f..874e49f7fa3d7ef63a5c55db8a1f86c4a6d08027 100644
--- a/src/libknot/util/libknot_error.c
+++ b/src/libknot/util/libknot_error.c
@@ -76,6 +76,7 @@ const error_table_t knot_error_msgs[] = {
 	{ZSCANNER_EBAD_GATEWAY, "Bad gateway!"},
 	{ZSCANNER_EBAD_APL, "Bad adress prefix list!"},
 	{ZSCANNER_EBAD_RDATA, "Bad record data!"},
+	{ZSCANNER_EBAD_HEX_RDATA, "Bad record data in hex format!"},
 	{ZSCANNER_EBAD_HEX_CHAR, "Bad hexadecimal character!"},
 	{ZSCANNER_EBAD_BASE64_CHAR, "Bad Base64 character!"},
 	{ZSCANNER_EBAD_BASE32HEX_CHAR, "Bad Base32hex character!"},
@@ -87,6 +88,7 @@ const error_table_t knot_error_msgs[] = {
 	{ZSCANNER_EBAD_TIME, "Bad time!"},
 	{ZSCANNER_EBAD_BITMAP, "Bad bitmap!"},
 	{ZSCANNER_ETEXT_OVERFLOW, "Text is too long!"},
+	{ZSCANNER_EBAD_TEXT, "Bad text string!"},
 	{ZSCANNER_EBAD_DIRECTIVE, "Bad directive!"},
 	{ZSCANNER_EBAD_TTL, "Bad zone TTL!"},
 	{ZSCANNER_EBAD_ORIGIN, "Bad zone origin!"},
diff --git a/src/zscanner/scanner.h b/src/zscanner/scanner.h
index 312591ad5a23e4603b462d5dbbb5f3403757d9ad..62feed394718df91e28fb9cf2472548e53812012 100644
--- a/src/zscanner/scanner.h
+++ b/src/zscanner/scanner.h
@@ -42,7 +42,7 @@
 #define INET4_ADDR_LENGTH       4
 #define INET6_ADDR_LENGTH      16
 
-#define RAGEL_STACK_SIZE        8 // But 2 should suffices (2 nested fcalls).
+#define RAGEL_STACK_SIZE        16 // Each nested call needs one.
 
 #define ASCII_0                48
 
diff --git a/src/zscanner/scanner_body.rl b/src/zscanner/scanner_body.rl
index 33dbf683169501d1e76c4b7ee0788da2374ceae3..543e79b1b1e79447705a440c38ca35b4595ff889 100644
--- a/src/zscanner/scanner_body.rl
+++ b/src/zscanner/scanner_body.rl
@@ -476,6 +476,10 @@
             fhold; fgoto err_line;
         }
     }
+    action _text_error {
+        SCANNER_ERROR(ZSCANNER_EBAD_TEXT);
+        fhold; fgoto err_line;
+    }
 
     action _text_dec_init {
         if (rdata_tail <= rdata_stop) {
@@ -502,11 +506,14 @@
            . digit {3}        $_text_dec %_text_dec_exit # "DDD" rest.
           )
         );
-    quoted_text_char = text_char | ([ \t;] $_text_char);
+    quoted_text_char =
+        ( text_char
+        | ([ \t;] | [\n] when { s->multiline }) $_text_char
+        );
 
     # Text string machine instantiation (for smaller code).
     text_ := (('\"' . quoted_text_char* . '\"') | text_char+)
-             %_ret . all_wchar;
+             $!_text_error %_ret . all_wchar;
     text = ^all_wchar ${ fhold; fcall text_; };
 
     # Text string with forward 1-byte length.
@@ -1382,10 +1389,23 @@
     # END
 
     # BEGIN - Hexadecimal rdata processing
+    action _hex_r_data_error {
+        SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+        fhold; fgoto err_line;
+    }
 
-    zero_hex_r_data = "\\#" . sep . '0';
-    hex_r_data      = "\\#" . sep . length_number . sep . type_data;
+    hex_r_data_ :=
+        (sep . length_number . sep . type_data)
+        $!_hex_r_data_error %_ret . end_wchar;
+    hex_r_data = "\\#" @{ fcall hex_r_data_; };
 
+    unknown_hex_r_data_ :=
+        (sep .
+         ( ('0'                             %_ret . all_wchar)
+         | (length_number . sep . type_data %_ret . end_wchar)
+         )
+        ) $!_hex_r_data_error;
+    unknown_hex_r_data = "\\#" @{ fcall unknown_hex_r_data_; };
     # END
 
     # BEGIN - Rdata processing
@@ -1536,137 +1556,180 @@
     }
 
     r_data_a :=
-        ( sep . ipv4_addr_write )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | ipv4_addr_write
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_ns :=
-        ( sep . r_dname )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | r_dname
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_soa :=
-        ( sep . r_dname . sep . r_dname . sep . num32 . sep . time32 .
-          sep . time32 . sep . time32 . sep . time32 )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep . 
+         ( hex_r_data
+         | r_dname . sep . r_dname . sep . num32 . sep . time32 . sep .
+           time32 . sep . time32 . sep . time32
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_hinfo :=
-        ( sep . text_item . sep . text_item )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | text_item . sep . text_item
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_minfo :=
-        ( sep . r_dname . sep . r_dname )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | r_dname . sep . r_dname
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_mx :=
-        ( sep . num16 . sep . r_dname )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | num16 . sep . r_dname
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_txt :=
-        ( sep . text_array )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | text_array
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_rp :=
-        ( sep . r_dname . sep . r_dname )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | r_dname . sep . r_dname
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_aaaa :=
-        ( sep . ipv6_addr_write )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | ipv6_addr_write
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_loc :=
-        ( sep . loc )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | loc
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_srv :=
-        ( sep . num16 . sep . num16 . sep . num16 . sep . r_dname )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | num16 . sep . num16 . sep . num16 . sep . r_dname
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_naptr :=
-        ( sep . num16 . sep . num16 . sep . text_item . sep .
-          text_item . sep . text_item . sep . r_dname )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | num16 . sep . num16 . sep . text_item . sep . text_item . sep .
+           text_item . sep . r_dname
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_cert :=
-        ( sep . num16 . sep . num16 . sep . num8 . sep . base64 )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | num16 . sep . num16 . sep . num8 . sep . base64
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_apl :=
-        ( sep . apl_array )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | apl_array
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_ds :=
-        ( sep . num16 . sep . num8 . sep . num8 . sep . hex_array )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | num16 . sep . num8 . sep . num8 . sep . hex_array
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_sshfp :=
-        ( sep . num8 . sep . num8 . sep . hex_array )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | num8 . sep . num8 . sep . hex_array
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_ipseckey :=
-        ( sep . num8 . sep . gateway . sep . base64 )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | num8 . sep . gateway . sep . base64
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_rrsig :=
-        ( sep . type_num . sep . num8 . sep . num8 . sep . num32 .
-          sep . timestamp . sep . timestamp . sep . num16 . sep . r_dname .
-          sep . base64 )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | type_num . sep . num8 . sep . num8 . sep . num32 . sep .
+           timestamp . sep . timestamp . sep . num16 . sep . r_dname .
+           sep . base64
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_nsec :=
-        ( sep . r_dname . bitmap )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | r_dname . bitmap
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_dnskey :=
-        ( sep . num16 . sep . num8 . sep . num8 . sep . base64 )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | num16 . sep . num8 . sep . num8 . sep . base64
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_dhcid :=
-        ( sep . base64 )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | base64
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_nsec3 :=
-        ( sep . num8 . sep . num8 . sep . num16 . sep . salt . sep .
-          hash . bitmap )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | num8 . sep . num8 . sep . num16 . sep . salt . sep . hash . bitmap
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_nsec3param :=
-        ( sep . num8 . sep . num8 . sep . num16 . sep . salt )
-        $!_r_data_error
-        %_ret . all_wchar;
+        (sep .
+         ( hex_r_data
+         | num8 . sep . num8 . sep . num16 . sep . salt
+         )
+        ) $!_r_data_error %_ret . all_wchar;
 
     r_data_tlsa :=
-        ( sep . num8 . sep . num8 . sep . num8 . sep . hex_array )
-        $!_r_data_error
-        %_ret . end_wchar;
+        (sep .
+         ( hex_r_data
+         | num8 . sep . num8 . sep . num8 . sep . hex_array
+         )
+        ) $!_r_data_error %_ret . end_wchar;
 
     r_data_type :=
-        ( sep .
-          ( zero_hex_r_data %_ret . all_wchar
-          | hex_r_data      %_ret . end_wchar
-          )
-        )
-        $!_r_data_error;
+        (sep . unknown_hex_r_data)
+        $!_r_data_error %_ret . all_wchar;
 
     r_type_r_data =
         ( "A"i                  %_r_data_a
diff --git a/src/zscanner/test/data/test1 b/src/zscanner/test/data/test1
index 3e75e2b8e555d0692c985395fddc9c7eccde4c72..9c4e29679c583cdfef5a8a6fbae6282577c9e12c 100644
--- a/src/zscanner/test/data/test1
+++ b/src/zscanner/test/data/test1
@@ -67,3 +67,4 @@ c TYPE6231  \# 1		05
 d TYPE0     \# 0
 e TYPE65535 \# 0
 e TYPE65536 \# 0
+  A \# 2  03040201
\ No newline at end of file
diff --git a/src/zscanner/test/data/test3 b/src/zscanner/test/data/test3
index 59ac4fa0343c243057cd8a0361fc8b61794122fc..f6da6f380ac5402e586b3b4a1b1a9a2143c1d85b 100644
--- a/src/zscanner/test/data/test3
+++ b/src/zscanner/test/data/test3
@@ -50,3 +50,8 @@ www.zdrojak.root.cz.    600     IN      NSEC    root.cz. A
  TXT "a ; b"
  TXT \043\ -
 
+ TXT (
+"one
+two
+three")
+ TXT next
\ No newline at end of file