diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
 # Changelog
 
+- 0.2.0 (2025-03-10)
+  * Fix bug in which inputs with uppercase hex characters failed to
+    decode.
+
 - 0.1.1 (2025-02-28)
   * Roughly 2x faster decoding performance.
 
diff --git a/lib/Data/ByteString/Base16.hs b/lib/Data/ByteString/Base16.hs
--- a/lib/Data/ByteString/Base16.hs
+++ b/lib/Data/ByteString/Base16.hs
@@ -125,8 +125,9 @@
 -- word8 hex character to word4
 word4 :: Word8 -> Maybe Word8
 word4 c
-  | c > 47 && c < 58  = pure $! c - 48
-  | c > 96 && c < 103 = pure $! c - 87
+  | c > 47 && c < 58  = pure $! c - 48 -- 0-9
+  | c > 64 && c < 71  = pure $! c - 55 -- A-F
+  | c > 96 && c < 103 = pure $! c - 87 -- a-f
   | otherwise         = Nothing
 {-# INLINE word4 #-}
 
diff --git a/ppad-base16.cabal b/ppad-base16.cabal
--- a/ppad-base16.cabal
+++ b/ppad-base16.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               ppad-base16
-version:            0.1.1
+version:            0.2.0
 synopsis:           Pure base16 encoding and decoding on bytestrings.
 license:            MIT
 license-file:       LICENSE
@@ -43,6 +43,7 @@
     , bytestring
     , ppad-base16
     , tasty
+    , tasty-hunit
     , tasty-quickcheck
 
 benchmark base16-bench
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -9,6 +9,7 @@
 import qualified "base16-bytestring" Data.ByteString.Base16 as R0
 import Test.Tasty
 import qualified Test.Tasty.QuickCheck as Q
+import qualified Test.Tasty.HUnit as H
 
 newtype BS = BS BS.ByteString
   deriving (Eq, Show)
@@ -48,6 +49,14 @@
           Left _ -> False
           Right d0 -> du == d0
 
+case_handled :: TestTree
+case_handled = H.testCase "decodes uppercase hex" $ do
+  let lhex = "deadbeef"
+      uhex = "DEADBEEF"
+  case liftA2 (,) (B16.decode lhex) (B16.decode uhex) of
+    Nothing -> H.assertBool mempty False
+    Just (a, b) -> H.assertEqual mempty a b
+
 main :: IO ()
 main = defaultMain $
   testGroup "ppad-base16" [
@@ -58,6 +67,9 @@
         Q.withMaxSuccess 5000 encode_matches_reference
     , Q.testProperty "decode matches reference" $
         Q.withMaxSuccess 5000 decode_matches_reference
+    ]
+  , testGroup "unit tests" [
+      case_handled
     ]
   ]
 
