diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,6 @@
+0.4.0.1
+* [Fix fragment serilization bug](https://github.com/Soostone/uri-bytestring/pull/65). 0.4.0.0 percent-decoded fragments on parse but did not percent-encode them on serialization, which made it possible for some URLs to not roundtrip.
+
 0.4.0.0
 * [Improve spec compliance ](https://github.com/Soostone/uri-bytestring/pull/64). Thanks to [hasufell](https://github.com/hasufell).
 
diff --git a/src/URI/ByteString/Internal.hs b/src/URI/ByteString/Internal.hs
--- a/src/URI/ByteString/Internal.hs
+++ b/src/URI/ByteString/Internal.hs
@@ -69,7 +69,16 @@
 
 -- | All normalization options disabled
 noNormalization :: URINormalizationOptions
-noNormalization = URINormalizationOptions False False False False False False False httpDefaultPorts
+noNormalization = URINormalizationOptions
+  { unoDowncaseScheme = False,
+    unoDowncaseHost = False,
+    unoDropDefPort = False,
+    unoSlashEmptyPath = False,
+    unoDropExtraSlashes = False,
+    unoSortParameters = False,
+    unoRemoveDotSegments = False,
+    unoDefaultPorts = httpDefaultPorts
+  }
 
 -------------------------------------------------------------------------------
 
@@ -117,7 +126,16 @@
 
 -- | All options enabled
 aggressiveNormalization :: URINormalizationOptions
-aggressiveNormalization = URINormalizationOptions True True True True True True True httpDefaultPorts
+aggressiveNormalization = URINormalizationOptions
+  { unoDowncaseScheme = True,
+    unoDowncaseHost = True,
+    unoDropDefPort = True,
+    unoSlashEmptyPath = True,
+    unoDropExtraSlashes = True,
+    unoSortParameters = True,
+    unoRemoveDotSegments = True,
+    unoDefaultPorts = httpDefaultPorts
+  }
 
 -------------------------------------------------------------------------------
 
@@ -285,7 +303,7 @@
 
 -------------------------------------------------------------------------------
 serializeFragment :: Maybe ByteString -> Builder
-serializeFragment = maybe mempty (\s -> c8 '#' <> bs s)
+serializeFragment = maybe mempty (\s -> c8 '#' <> urlEncodeQuery s)
 
 serializeFragment' :: Maybe ByteString -> ByteString
 serializeFragment' = BB.toByteString . serializeFragment
diff --git a/test/URI/ByteStringTests.hs b/test/URI/ByteStringTests.hs
--- a/test/URI/ByteStringTests.hs
+++ b/test/URI/ByteStringTests.hs
@@ -210,6 +210,11 @@
       roundtripTestURI strictURIParserOptions "news:comp.infosystems.www.servers.unix",
       roundtripTestURI strictURIParserOptions "tel:+1-816-555-1212",
       roundtripTestURI strictURIParserOptions "telnet://192.0.2.16:80/",
+      -- percent encoding in queries and fragments
+      roundtripTestURI strictURIParserOptions "http://example.com/foo#bar%20baz",
+      roundtripTestURI strictURIParserOptions "http://example.com/foo?bar%20baz=quux",
+      roundtripTestURI strictURIParserOptions "http://example.com/foo?bar=baz%20quux",
+      roundtripTestURI strictURIParserOptions "http://example.com/foo?bar=baz%20quux#bar%20baz",
       -- RFC 3986, Section 4.2
       parseTestRelativeRef strictURIParserOptions "verysimple" $
         Right $
diff --git a/uri-bytestring.cabal b/uri-bytestring.cabal
--- a/uri-bytestring.cabal
+++ b/uri-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                uri-bytestring
-version:             0.4.0.0
+version:             0.4.0.1
 synopsis:            Haskell URI parsing as ByteStrings
 description: uri-bytestring aims to be an RFC3986 compliant URI parser that uses efficient ByteStrings for parsing and representing the URI data.
 license:             BSD3
