diff --git a/src/Network/URI/Template/Parser.hs b/src/Network/URI/Template/Parser.hs
--- a/src/Network/URI/Template/Parser.hs
+++ b/src/Network/URI/Template/Parser.hs
@@ -172,7 +172,11 @@
 -- | Parse a URI template segments
 {-# INLINE uriTemplate #-}
 uriTemplate :: Parser e (V.Vector TemplateSegment)
-uriTemplate = V.fromList <$> (ws *> many (literal <|> embed))
+uriTemplate = do
+  ws
+  segments <- many (literal <|> embed)
+  eof  -- Ensure we consumed all input
+  return (V.fromList segments)
 
 
 -- | Helper to separate a parser by a separator
@@ -181,13 +185,33 @@
 sepBy1 p sep = (:) <$> p <*> many (sep *> p)
 
 
+-- | Analyze parse failure to provide a better error message
+analyzeParseFailure :: String -> ParseError
+analyzeParseFailure input = go 0 0 input
+ where
+  go depth pos []
+    | depth > 0 = UnterminatedExpression (findLastOpen input)
+    | otherwise = GenericParseError ("Parse error in URI template: " ++ input)
+  go depth pos ('{' : rest) = go (depth + 1) (pos + 1) rest
+  go depth pos ('}' : rest)
+    | depth <= 0 = UnexpectedCharacter pos '}' "Unexpected closing brace without matching opening brace"
+    | otherwise = go (depth - 1) (pos + 1) rest
+  go depth pos (_ : rest) = go depth (pos + 1) rest
+
+  findLastOpen = go' 0 0
+   where
+    go' pos lastPos [] = lastPos
+    go' pos lastPos ('{' : rest) = go' (pos + 1) pos rest
+    go' pos lastPos (_ : rest) = go' (pos + 1) lastPos rest
+
+
 -- | Parse a template from a String
 parseTemplate :: String -> Either ParseError UriTemplate
 parseTemplate input =
   case runParser uriTemplate (TE.encodeUtf8 $ T.pack input) of
     OK result _ -> Right (UriTemplate result)
-    Err _ -> Left (GenericParseError ("Parse error in URI template: " ++ input))
-    Fail -> Left (GenericParseError ("Parse error in URI template: " ++ input))
+    Err _ -> Left (analyzeParseFailure input)
+    Fail -> Left (analyzeParseFailure input)
 
 
 {- | 'IsString' instance for 'UriTemplate' allows using string literals directly as templates
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -18,6 +18,7 @@
 import qualified Data.Vector as V
 import GHC.Generics (Generic, Rep)
 import Network.URI.Template
+import Network.URI.Template.Error
 import Network.URI.Template.Parser
 import Network.URI.Template.TH
 import Network.URI.Template.Types
@@ -191,6 +192,50 @@
       rendered @?= ("?gen_product_name=Gadget&gen_product_price=200" :: Text)
 
 
+parseErrorTests :: TestRegistry ()
+parseErrorTests = label "Parse Error Tests" $
+  suite $ do
+    label "Unclosed template expression (missing closing brace)" $ test $ do
+      case parseTemplate "http://example.com/dictionary/{term:1}/{term" of
+        Left (UnterminatedExpression _) -> return ()
+        Left err -> assertFailure $ "Expected UnterminatedExpression, got: " ++ show err
+        Right _ -> assertFailure "Should fail to parse template with missing closing brace"
+
+    label "Unopened closing brace (orphan closing brace)" $ test $ do
+      case parseTemplate "http://example.com/dictionary/{term:1}/term}" of
+        Left (UnexpectedCharacter _ '}' _) -> return ()
+        Left err -> assertFailure $ "Expected UnexpectedCharacter for '}', got: " ++ show err
+        Right _ -> assertFailure "Should fail to parse template with extra closing brace"
+
+    label "Multiple unclosed braces" $ test $ do
+      case parseTemplate "{foo}{bar" of
+        Left (UnterminatedExpression _) -> return ()
+        Left err -> assertFailure $ "Expected UnterminatedExpression, got: " ++ show err
+        Right _ -> assertFailure "Should fail to parse template with unclosed brace"
+
+    label "Nested braces (invalid)" $ test $ do
+      case parseTemplate "{foo{bar}}" of
+        Left _ -> return ()
+        Right _ -> assertFailure "Should fail to parse template with nested braces"
+
+    label "Only opening brace" $ test $ do
+      case parseTemplate "{" of
+        Left (UnterminatedExpression _) -> return ()
+        Left err -> assertFailure $ "Expected UnterminatedExpression, got: " ++ show err
+        Right _ -> assertFailure "Should fail to parse template with only opening brace"
+
+    label "Only closing brace" $ test $ do
+      case parseTemplate "}" of
+        Left (UnexpectedCharacter _ '}' _) -> return ()
+        Left err -> assertFailure $ "Expected UnexpectedCharacter for '}', got: " ++ show err
+        Right _ -> assertFailure "Should fail to parse template with only closing brace"
+
+    label "Valid template should still parse correctly" $ test $ do
+      case parseTemplate "http://example.com/dictionary/{term:1}/{term}" of
+        Right _ -> return ()
+        Left err -> assertFailure $ "Valid template should parse, got error: " ++ show err
+
+
 main :: IO ()
 main = do
   counts <- testRun
@@ -210,6 +255,7 @@
     thDerivationTests
     genericsDerivationTests
     percentEncodingTests
+    parseErrorTests
     label "RFC 6570 Core Examples" $
       suite $ do
         label "unescaped" $ test $ unescaped strEq
diff --git a/uri-templater.cabal b/uri-templater.cabal
--- a/uri-templater.cabal
+++ b/uri-templater.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                uri-templater
-version:             1.0.0
+version:             1.0.0.1
 synopsis:            Parsing & Quasiquoting for RFC 6570 URI Templates
 description:         Parsing & Quasiquoting for RFC 6570 URI Templates
 homepage:            https://github.com/iand675/uri-templater
