diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,14 @@
 # Changelog
 
+## 0.3.3 (Oct 2026)
+
+### Bug Fixes
+
+* On Windows, reading a directory, e.g. with `read` or `readEither` in
+  `Streamly.FileSystem.DirIO`, could fail with a "does not exist" error
+  for an existing directory. The search pattern passed to `FindFirstFileW`
+  was not terminated with a two byte NUL.
+
 ## 0.3.2 (Oct 2026)
 
 ### Bug Fixes
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for streamly-core 0.3.2.
+# Generated by GNU Autoconf 2.72 for streamly-core 0.3.3.
 #
 # Report bugs to <streamly@composewell.com>.
 #
@@ -603,8 +603,8 @@
 # Identity of this package.
 PACKAGE_NAME='streamly-core'
 PACKAGE_TARNAME='streamly-core'
-PACKAGE_VERSION='0.3.2'
-PACKAGE_STRING='streamly-core 0.3.2'
+PACKAGE_VERSION='0.3.3'
+PACKAGE_STRING='streamly-core 0.3.3'
 PACKAGE_BUGREPORT='streamly@composewell.com'
 PACKAGE_URL='https://streamly.composewell.com'
 
@@ -1249,7 +1249,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures streamly-core 0.3.2 to adapt to many kinds of systems.
+'configure' configures streamly-core 0.3.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1311,7 +1311,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of streamly-core 0.3.2:";;
+     short | recursive ) echo "Configuration of streamly-core 0.3.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1397,7 +1397,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-streamly-core configure 0.3.2
+streamly-core configure 0.3.3
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -1621,7 +1621,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by streamly-core $as_me 0.3.2, which was
+It was created by streamly-core $as_me 0.3.3, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3881,7 +3881,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by streamly-core $as_me 0.3.2, which was
+This file was extended by streamly-core $as_me 0.3.3, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -3937,7 +3937,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-streamly-core config.status 0.3.2
+streamly-core config.status 0.3.3
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@
 # See https://www.gnu.org/software/autoconf/manual/autoconf.html for help on
 # the macros used in this file.
 
-AC_INIT([streamly-core], [0.3.2], [streamly@composewell.com], [streamly-core], [https://streamly.composewell.com])
+AC_INIT([streamly-core], [0.3.3], [streamly@composewell.com], [streamly-core], [https://streamly.composewell.com])
 
 # To suppress "WARNING: unrecognized options: --with-compiler"
 AC_ARG_WITH([compiler], [GHC])
diff --git a/docs/Changelog.md b/docs/Changelog.md
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,5 +1,14 @@
 # Changelog
 
+## 0.3.3 (Oct 2026)
+
+### Bug Fixes
+
+* On Windows, reading a directory, e.g. with `read` or `readEither` in
+  `Streamly.FileSystem.DirIO`, could fail with a "does not exist" error
+  for an existing directory. The search pattern passed to `FindFirstFileW`
+  was not terminated with a two byte NUL.
+
 ## 0.3.2 (Oct 2026)
 
 ### Bug Fixes
diff --git a/src/Streamly/Internal/FileSystem/Windows/ReadDir.hsc b/src/Streamly/Internal/FileSystem/Windows/ReadDir.hsc
--- a/src/Streamly/Internal/FileSystem/Windows/ReadDir.hsc
+++ b/src/Streamly/Internal/FileSystem/Windows/ReadDir.hsc
@@ -149,7 +149,7 @@
     fp_finddata <- mallocForeignPtrBytes (# const sizeof(WIN32_FIND_DATAW) )
     withForeignPtr fp_finddata $ \dataPtr -> do
         handle <-
-            Array.asCStringUnsafe (Path.toArray path) $ \pathPtr -> do
+            Array.asCWString (Path.toArray path) $ \pathPtr -> do
                 -- XXX Use getLastError to distinguish the case when no
                 -- matching file is found. See the doc of FindFirstFileW.
                 failIf
diff --git a/streamly-core.cabal b/streamly-core.cabal
--- a/streamly-core.cabal
+++ b/streamly-core.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               streamly-core
-version:            0.3.2
+version:            0.3.3
 synopsis:           Streaming, parsers, arrays, serialization and more
 description:
   For upgrading to streamly-0.9.0+ please read the
