diff --git a/src/libraries/datatype/unmarshal.ml b/src/libraries/datatype/unmarshal.ml
index 888573ad32561e550d7ee883224466c68a787de1..314dadf1be0bc74b5a431dddd1ef5192f0376eb6 100644
--- a/src/libraries/datatype/unmarshal.ml
+++ b/src/libraries/datatype/unmarshal.ml
@@ -472,13 +472,25 @@ let input_val ch t =
           let clos = intern_rec [] t in
           return stk (Obj.add_offset (Obj.repr clos) ofs)
 
-      | 0x12 (* CODE_CUSTOM *) ->
+      | 0x12 | 0x19 (* CODE_CUSTOM (deprecated) or CODE_CUSTOM_FIXED *) ->
           let id = read_customident ch in
           let v = read_custom ch id in
           let dest = !ctr in
           ctr := dest + 1;
           return_block stk t v dest
 
+      | 0x18 (* CODE_CUSTOM_LEN *) ->
+        let id = read_customident ch in
+        (* Note: CODE_CUSTOM_FIXED and CODE_CUSTOM_LEN has the length of the
+           payload statically computable, but contrary to the C code,
+           we don't check that the size matches. *)
+        let _sz_32 = read32u ch in
+        let _sz_64 = read64u ch in
+        let v = read_custom ch id in
+        let dest = !ctr in
+        ctr := dest + 1;
+        return_block stk t v dest
+
       | _ when code >= 0x80 (* PREFIX_SMALL_BLOCK *) ->
           let tag = code land 0xF in
           let size = (code lsr 4) land 0x7 in
@@ -491,7 +503,7 @@ let input_val ch t =
           read_string stk t len
 
       | _ ->
-	  ill_formed (Printf.sprintf "code %x" code)
+	  ill_formed (Printf.sprintf "code 0x%x" code)
     in
     match t with
     | Dynamic f ->