diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,6 @@
 # Revision history for Z-Data
 
-## 0.8.6.0  -- 2021-06-09
+## 0.8.6.1  -- 2021-06-09
 
 * Change SIMD base64 codec to https://github.com/lemire/fastbase64.
 * Add SIMD enabled `count` from bytestring.
diff --git a/Z-Data.cabal b/Z-Data.cabal
--- a/Z-Data.cabal
+++ b/Z-Data.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               Z-Data
-version:            0.8.6.0
+version:            0.8.6.1
 synopsis:           Array, vector and text
 description:        This package provides array, slice and text operations
 license:            BSD-3-Clause
diff --git a/Z/Data/Vector/Base64.hs b/Z/Data/Vector/Base64.hs
--- a/Z/Data/Vector/Base64.hs
+++ b/Z/Data/Vector/Base64.hs
@@ -68,12 +68,12 @@
     | inputLen == 0 = Just V.empty
     | decodeLen == -1 = Nothing
     | otherwise = unsafeDupablePerformIO $ do
-        ((V.PrimVector arr s' _), r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
-            allocPrimVectorUnsafe decodeLen $ \ buf# ->
+        (arr, r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
+            allocPrimArrayUnsafe decodeLen $ \ buf# ->
                 hs_base64_decode buf# ba# s l
         if r == 0
         then return Nothing
-        else return (Just (V.PrimVector arr s' r))
+        else return (Just (V.PrimVector arr 0 r))
   where
     inputLen = V.length ba
     decodeLen = base64DecodeLength inputLen
@@ -87,26 +87,16 @@
 -- | Decode a base64 encoding string, throw 'Base64DecodeException' on error.
 base64Decode' :: HasCallStack => V.Bytes -> V.Bytes
 {-# INLINABLE base64Decode' #-}
-base64Decode' ba
-    | inputLen == 0 = V.empty
-    | decodeLen == -1 = throw (IncompleteBase64Bytes ba callStack)
-    | otherwise = unsafeDupablePerformIO $ do
-        ((V.PrimVector arr s' _), r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
-            allocPrimVectorUnsafe decodeLen $ \ buf# ->
-                hs_base64_decode buf# ba# s l
-        if r == 0
-        then throwIO (IllegalBase64Bytes ba callStack)
-        else return (V.PrimVector arr s' r)
-  where
-    inputLen = V.length ba
-    decodeLen = base64DecodeLength inputLen
+base64Decode' ba = case base64Decode ba of
+    Just r -> r
+    _ -> throw (IllegalBase64Bytes ba callStack)
 
 -- | Return the upper bound of decoded length of a given input length
 -- , return -1 if illegal(not a multipler of 4).
 base64DecodeLength :: Int -> Int
 {-# INLINABLE base64DecodeLength #-}
 base64DecodeLength n | n .&. 3 == 1 = -1
-                     | otherwise = (n `unsafeShiftR` 2) * 3
+                     | otherwise = (n `unsafeShiftR` 2) * 3 + 2
 
 --------------------------------------------------------------------------------
 
diff --git a/Z/Data/Vector/Hex.hs b/Z/Data/Vector/Hex.hs
--- a/Z/Data/Vector/Hex.hs
+++ b/Z/Data/Vector/Hex.hs
@@ -100,12 +100,12 @@
     | V.length ba == 0 = Just V.empty
     | V.length ba .&. 1 == 1 = Nothing
     | otherwise = unsafeDupablePerformIO $ do
-        (out, r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
-            allocPrimVectorUnsafe (l `unsafeShiftR` 1) $ \ buf# ->
+        (arr, r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
+            allocPrimArrayUnsafe (l `unsafeShiftR` 1) $ \ buf# ->
                 hs_hex_decode buf# ba# s l
         if r < 0
         then return Nothing
-        else return (Just out)
+        else return (Just (V.PrimVector arr 0 r))
 
 -- | Decode a hex encoding string, ignore ASCII whitespace(space, tab, newline, vertical tab, form feed, carriage return).
 --
@@ -121,14 +121,12 @@
 hexDecodeWS ba
     | V.length ba == 0 = Just V.empty
     | otherwise = unsafeDupablePerformIO $ do
-        (out, r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
-            allocPrimVectorUnsafe (l `unsafeShiftR` 1) $ \ buf# ->
+        (arr, r) <- withPrimVectorUnsafe ba $ \ ba# s l ->
+            allocPrimArrayUnsafe (l `unsafeShiftR` 1) $ \ buf# ->
                 hs_hex_decode_ws buf# ba# s l
         if r < 0
         then return Nothing
-        else do
-            let !out' = V.unsafeTake r out
-            return (Just out')
+        else return (Just (V.PrimVector arr 0 r))
 
 -- | Exception during hex decoding.
 data HexDecodeException = IllegalHexBytes V.Bytes CallStack
diff --git a/cbits/bytes.c b/cbits/bytes.c
--- a/cbits/bytes.c
+++ b/cbits/bytes.c
@@ -251,6 +251,7 @@
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
 HsInt hs_hex_decode(uint8_t* output, const uint8_t* input, HsInt input_off, HsInt input_length) {
+    uint8_t* out = output;
     input = input+input_off;
     for(size_t i = 0; i != input_length;) {
         const uint8_t hi = HEX_TO_BIN[input[i++]];
@@ -259,15 +260,15 @@
             return -1;
         }
         else {
-            *(output++) = hi << 4 | lo;
+            *(out++) = hi << 4 | lo;
         }
     }
-    return 0;
+    return out - output;
 }
 
 HsInt hs_hex_decode_ws(uint8_t* output, const uint8_t* input, HsInt input_off, HsInt input_length) {
-    input = input+input_off;
     uint8_t* out = output;
+    input = input+input_off;
     for(size_t i = 0; i != input_length;) {
         const uint8_t w1 = input[i++];
         
diff --git a/third_party/fastbase64/src/chromiumbase64.c b/third_party/fastbase64/src/chromiumbase64.c
--- a/third_party/fastbase64/src/chromiumbase64.c
+++ b/third_party/fastbase64/src/chromiumbase64.c
@@ -338,7 +338,7 @@
         *p++ = CHARPAD;
     }
 
-    *p = '\0';
+    // *p = '\0'; don't do this in ZHaskell
     return p - (uint8_t*)dest;
 }
 
