diff --git a/Network/HPACK.hs b/Network/HPACK.hs
--- a/Network/HPACK.hs
+++ b/Network/HPACK.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE CPP #-}
 
--- | HPACK: encoding and decoding a header list.
+-- | HPACK(<https://tools.ietf.org/html/rfc7541>) encoding and decoding a header list.
 module Network.HPACK (
   -- * Encoding and decoding
     HPACKEncoding
@@ -15,6 +15,7 @@
   , defaultDynamicTableSize
   , newDynamicTableForEncoding
   , newDynamicTableForDecoding
+  , setLimitForEncoding
   -- * Strategy for encoding
   , CompressionAlgo(..)
   , EncodeStrategy(..)
@@ -39,7 +40,7 @@
 import Data.ByteString (ByteString)
 import Data.ByteString.Builder (Builder)
 import Network.HPACK.HeaderBlock (toHeaderBlock, fromHeaderBlock, toByteString, fromByteString, toBuilder)
-import Network.HPACK.Table (DynamicTable, Size, newDynamicTableForEncoding, newDynamicTableForDecoding)
+import Network.HPACK.Table (DynamicTable, Size, newDynamicTableForEncoding, newDynamicTableForDecoding, setLimitForEncoding)
 import Network.HPACK.Types
 
 -- | Default dynamic table size.
diff --git a/Network/HPACK/HeaderBlock/From.hs b/Network/HPACK/HeaderBlock/From.hs
--- a/Network/HPACK/HeaderBlock/From.hs
+++ b/Network/HPACK/HeaderBlock/From.hs
@@ -8,6 +8,8 @@
 #if __GLASGOW_HASKELL__ < 709
 import Control.Applicative ((<$>))
 #endif
+import Control.Exception (throwIO)
+import Control.Monad (unless)
 import Network.HPACK.Builder
 import Network.HPACK.HeaderBlock.HeaderField
 import Network.HPACK.Table
@@ -22,52 +24,53 @@
 fromHeaderBlock :: DynamicTable
                 -> HeaderBlock
                 -> IO (DynamicTable, HeaderList)
-fromHeaderBlock !hdrtbl rs = decodeLoop rs (hdrtbl,empty)
+fromHeaderBlock !dyntbl rs = decodeLoop rs (dyntbl,empty)
 
 ----------------------------------------------------------------
 
 decodeLoop :: HeaderBlock -> Ctx -> IO (DynamicTable, HeaderList)
-decodeLoop (r:rs) !hdrtbl = decodeStep hdrtbl r >>= decodeLoop rs
-decodeLoop []     !hdrtbl = decodeFinal hdrtbl
+decodeLoop (r:rs) !dyntbl = decodeStep dyntbl r >>= decodeLoop rs
+decodeLoop []     !dyntbl = decodeFinal dyntbl
 
 ----------------------------------------------------------------
 
 -- | Decoding step for one 'HeaderField'. Exporting for the
 --   test purpose.
 decodeStep :: Step
-decodeStep (!hdrtbl,!builder) (ChangeTableSize siz) = do
-    hdrtbl' <- renewDynamicTable siz hdrtbl
-    return (hdrtbl',builder)
-decodeStep (!hdrtbl,!builder) (Indexed idx) = do
-      w <- which hdrtbl idx
+decodeStep (!dyntbl,!builder) (ChangeTableSize siz) = do
+    unless (isSuitableSize siz dyntbl) $ throwIO TooLargeTableSize
+    dyntbl' <- renewDynamicTable siz dyntbl
+    return (dyntbl',builder)
+decodeStep (!dyntbl,!builder) (Indexed idx) = do
+      w <- which dyntbl idx
       case w of
           (InStaticTable, e) -> do
               let b = builder << fromEntry e
-              return (hdrtbl,b)
+              return (dyntbl,b)
           (InDynamicTable, e) -> do
               let b = builder << fromEntry e
-              return (hdrtbl,b)
-decodeStep (!hdrtbl,!builder) (Literal NotAdd naming v) = do
-    k <- fromNaming naming hdrtbl
+              return (dyntbl,b)
+decodeStep (!dyntbl,!builder) (Literal NotAdd naming v) = do
+    k <- fromNaming naming dyntbl
     let b = builder << (k,v)
-    return (hdrtbl, b)
-decodeStep (!hdrtbl,!builder) (Literal Never naming v) = do
-    k <- fromNaming naming hdrtbl
+    return (dyntbl, b)
+decodeStep (!dyntbl,!builder) (Literal Never naming v) = do
+    k <- fromNaming naming dyntbl
     let b = builder << (k,v)
-    return (hdrtbl, b)
-decodeStep (!hdrtbl,!builder) (Literal Add naming v) = do
-    k <- fromNaming naming hdrtbl
+    return (dyntbl, b)
+decodeStep (!dyntbl,!builder) (Literal Add naming v) = do
+    k <- fromNaming naming dyntbl
     let h = (k,v)
         e = toEntry (k,v)
         b = builder << h
-    hdrtbl' <- insertEntry e hdrtbl
-    return (hdrtbl',b)
+    dyntbl' <- insertEntry e dyntbl
+    return (dyntbl',b)
 
 decodeFinal :: Ctx -> IO (DynamicTable, HeaderList)
-decodeFinal (!hdrtbl, !builder) = return (hdrtbl, run builder)
+decodeFinal (!dyntbl, !builder) = return (dyntbl, run builder)
 
 ----------------------------------------------------------------
 
 fromNaming :: Naming -> DynamicTable -> IO HeaderName
 fromNaming (Lit k)   _   = return k
-fromNaming (Idx idx) hdrtbl = entryHeaderName . snd <$> which hdrtbl idx
+fromNaming (Idx idx) dyntbl = entryHeaderName . snd <$> which dyntbl idx
diff --git a/Network/HPACK/HeaderBlock/To.hs b/Network/HPACK/HeaderBlock/To.hs
--- a/Network/HPACK/HeaderBlock/To.hs
+++ b/Network/HPACK/HeaderBlock/To.hs
@@ -1,9 +1,13 @@
-{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+{-# LANGUAGE BangPatterns, OverloadedStrings, CPP #-}
 
 module Network.HPACK.HeaderBlock.To (
     toHeaderBlock
   ) where
 
+#if __GLASGOW_HASKELL__ < 709
+import Control.Applicative ((<$>))
+#endif
+import Control.Arrow (second)
 import Network.HPACK.Builder
 import Network.HPACK.HeaderBlock.HeaderField
 import Network.HPACK.Table
@@ -17,39 +21,56 @@
               -> DynamicTable
               -> HeaderList
               -> IO (DynamicTable, HeaderBlock)
-toHeaderBlock Naive  !hdrtbl hs = encodeLoop naiveStep  hs (hdrtbl,empty)
-toHeaderBlock Static !hdrtbl hs = encodeLoop staticStep hs (hdrtbl,empty)
-toHeaderBlock Linear !hdrtbl hs = encodeLoop linearStep hs (hdrtbl,empty)
+toHeaderBlock algo !dyntbl hs = do
+    msiz <- needChangeTableSize dyntbl
+    (dyntbl', op) <- case msiz of
+        Keep -> do
+            return (dyntbl, id)
+        Change lim -> do
+            tbl <- renewDynamicTable lim dyntbl
+            return (tbl, (ChangeTableSize lim :))
+        Ignore lim -> do
+            resetLimitForEncoding dyntbl
+            return (dyntbl, (ChangeTableSize lim :))
+    second op <$> toHeaderBlock' algo dyntbl' hs
 
+toHeaderBlock' :: CompressionAlgo
+              -> DynamicTable
+              -> HeaderList
+              -> IO (DynamicTable, HeaderBlock)
+toHeaderBlock' Naive  !dyntbl hs = encodeLoop naiveStep  hs (dyntbl,empty)
+toHeaderBlock' Static !dyntbl hs = encodeLoop staticStep hs (dyntbl,empty)
+toHeaderBlock' Linear !dyntbl hs = encodeLoop linearStep hs (dyntbl,empty)
+
 ----------------------------------------------------------------
 
 encodeFinal :: Ctx -> IO (DynamicTable, HeaderBlock)
-encodeFinal (!hdrtbl, !builder) = return (hdrtbl, run builder)
+encodeFinal (!dyntbl, !builder) = return (dyntbl, run builder)
 
 encodeLoop :: Step
            -> HeaderList
            -> Ctx
            -> IO (DynamicTable, HeaderBlock)
-encodeLoop step (h:hs) !hdrtbl = step hdrtbl h >>= encodeLoop step hs
-encodeLoop _    []     !hdrtbl = encodeFinal hdrtbl
+encodeLoop step (h:hs) !dyntbl = step dyntbl h >>= encodeLoop step hs
+encodeLoop _    []     !dyntbl = encodeFinal dyntbl
 
 ----------------------------------------------------------------
 
 naiveStep :: Step
-naiveStep (!hdrtbl,!builder) (k,v) = do
+naiveStep (!dyntbl,!builder) (k,v) = do
     let builder' = builder << Literal NotAdd (Lit k) v
-    return (hdrtbl, builder')
+    return (dyntbl, builder')
 
 ----------------------------------------------------------------
 
 staticStep :: Step
-staticStep (!hdrtbl,!builder) h@(k,v) = return (hdrtbl, builder')
+staticStep (!dyntbl,!builder) h@(k,v) = return (dyntbl, builder')
   where
-    b = case lookupTable h hdrtbl of
-        None                     -> Literal NotAdd (Lit k) v
-        KeyOnly  InStaticTable i -> Literal NotAdd (Idx i) v
+    b = case lookupTable h dyntbl of
+        None                      -> Literal NotAdd (Lit k) v
+        KeyOnly  InStaticTable i  -> Literal NotAdd (Idx i) v
         KeyOnly  InDynamicTable _ -> Literal NotAdd (Lit k) v
-        KeyValue InStaticTable i -> Literal NotAdd (Idx i) v
+        KeyValue InStaticTable i  -> Literal NotAdd (Idx i) v
         KeyValue InDynamicTable _ -> Literal NotAdd (Lit k) v
     builder' = builder << b
 
@@ -58,32 +79,32 @@
 -- by 'Index 0' and uses indexing as much as possible.
 
 linearStep :: Step
-linearStep cb@(!hdrtbl,!builder) h = smartStep linear cb h
+linearStep cb@(!dyntbl,!builder) h = smartStep linear cb h
   where
-    linear i = return (hdrtbl,builder << Indexed i)
+    linear i = return (dyntbl,builder << Indexed i)
 
 ----------------------------------------------------------------
 
 smartStep :: (Index -> IO Ctx) -> Step
-smartStep func cb@(!hdrtbl,!builder) h@(k,_) = do
-    let cache = lookupTable h hdrtbl
+smartStep func cb@(!dyntbl,!builder) h@(k,_) = do
+    let cache = lookupTable h dyntbl
     case cache of
         None                      -> check cb h (Lit k)
         KeyOnly  InStaticTable i  -> check cb h (Idx i)
         KeyOnly  InDynamicTable i -> check cb h (Idx i)
-        KeyValue InStaticTable i  -> return (hdrtbl, builder << Indexed i)
+        KeyValue InStaticTable i  -> return (dyntbl, builder << Indexed i)
         KeyValue InDynamicTable i -> func i
 
 check :: Ctx -> Header -> Naming -> IO Ctx
-check (hdrtbl,builder) h@(k,v) x
+check (dyntbl,builder) h@(k,v) x
   | k `elem` headersNotToIndex = do
       let builder' = builder << Literal NotAdd x v
-      return (hdrtbl, builder')
+      return (dyntbl, builder')
   | otherwise = do
       let e = toEntry h
-      hdrtbl' <- insertEntry e hdrtbl
+      dyntbl' <- insertEntry e dyntbl
       let builder' = builder << Literal Add x v
-      return (hdrtbl', builder')
+      return (dyntbl', builder')
 
 headersNotToIndex :: [HeaderName]
 headersNotToIndex = [
diff --git a/Network/HPACK/Table.hs b/Network/HPACK/Table.hs
--- a/Network/HPACK/Table.hs
+++ b/Network/HPACK/Table.hs
@@ -8,6 +8,11 @@
   , renewDynamicTable
   , printDynamicTable
   , isDynamicTableEmpty
+  , isSuitableSize
+  , TableSizeAction(..)
+  , needChangeTableSize
+  , setLimitForEncoding
+  , resetLimitForEncoding
   -- * Insertion
   , insertEntry
   -- * Header to index
@@ -45,21 +50,21 @@
 -- | Resolving an index from a header.
 --   Static table is prefer to dynamic table.
 lookupTable :: Header -> DynamicTable -> HeaderCache
-lookupTable h hdrtbl = case reverseIndex hdrtbl of
+lookupTable h dyntbl = case reverseIndex dyntbl of
     Nothing            -> None
     Just rev -> case DHM.search h rev of
         DHM.N       -> case mstatic of
             DHM.N       -> None
-            DHM.K  sidx -> KeyOnly  InStaticTable (fromSIndexToIndex hdrtbl sidx)
-            DHM.KV sidx -> KeyValue InStaticTable (fromSIndexToIndex hdrtbl sidx)
+            DHM.K  sidx -> KeyOnly  InStaticTable  (fromSIndexToIndex dyntbl sidx)
+            DHM.KV sidx -> KeyValue InStaticTable  (fromSIndexToIndex dyntbl sidx)
         DHM.K hidx  -> case mstatic of
-            DHM.N       -> KeyOnly  InDynamicTable (fromHIndexToIndex hdrtbl hidx)
-            DHM.K  sidx -> KeyOnly  InStaticTable (fromSIndexToIndex hdrtbl sidx)
-            DHM.KV sidx -> KeyValue InStaticTable (fromSIndexToIndex hdrtbl sidx)
+            DHM.N       -> KeyOnly  InDynamicTable (fromHIndexToIndex dyntbl hidx)
+            DHM.K  sidx -> KeyOnly  InStaticTable  (fromSIndexToIndex dyntbl sidx)
+            DHM.KV sidx -> KeyValue InStaticTable  (fromSIndexToIndex dyntbl sidx)
         DHM.KV hidx -> case mstatic of
-            DHM.N       -> KeyValue InDynamicTable (fromHIndexToIndex hdrtbl hidx)
-            DHM.K  _    -> KeyValue InDynamicTable (fromHIndexToIndex hdrtbl hidx)
-            DHM.KV sidx -> KeyValue InStaticTable (fromSIndexToIndex hdrtbl sidx)
+            DHM.N       -> KeyValue InDynamicTable (fromHIndexToIndex dyntbl hidx)
+            DHM.K  _    -> KeyValue InDynamicTable (fromHIndexToIndex dyntbl hidx)
+            DHM.KV sidx -> KeyValue InStaticTable  (fromSIndexToIndex dyntbl sidx)
   where
     mstatic = DHM.search h staticHashPSQ
 
@@ -70,10 +75,10 @@
 
 -- | Which table does 'Index' belong to?
 which :: DynamicTable -> Index -> IO (WhichTable, Entry)
-which hdrtbl idx
-  | idx `isIn` hdrtbl  = (InDynamicTable,) <$> toHeaderEntry hdrtbl hidx
+which dyntbl idx
+  | idx `isIn` dyntbl  = (InDynamicTable,) <$> toHeaderEntry dyntbl hidx
   | isSIndexValid sidx = return (InStaticTable, toStaticEntry sidx)
   | otherwise          = throwIO $ IndexOverrun idx
   where
-    hidx = fromIndexToHIndex hdrtbl idx
-    sidx = fromIndexToSIndex hdrtbl idx
+    hidx = fromIndexToHIndex dyntbl idx
+    sidx = fromIndexToSIndex dyntbl idx
diff --git a/Network/HPACK/Table/Dynamic.hs b/Network/HPACK/Table/Dynamic.hs
--- a/Network/HPACK/Table/Dynamic.hs
+++ b/Network/HPACK/Table/Dynamic.hs
@@ -7,6 +7,11 @@
   , renewDynamicTable
   , printDynamicTable
   , isDynamicTableEmpty
+  , isSuitableSize
+  , TableSizeAction(..)
+  , needChangeTableSize
+  , setLimitForEncoding
+  , resetLimitForEncoding
   , insertEntry
   , toHeaderEntry
   , fromHIndexToIndex
@@ -15,12 +20,13 @@
   , fromIndexToSIndex
   ) where
 
+import Control.Monad (forM)
 import Data.Array.IO (IOArray, newArray, readArray, writeArray)
 import qualified Data.ByteString.Char8 as BS
-import Network.HPACK.Table.Entry
+import Data.IORef
 import qualified Network.HPACK.Table.DoubleHashMap as DHM
+import Network.HPACK.Table.Entry
 import Network.HPACK.Table.Static
-import Control.Monad (forM)
 
 ----------------------------------------------------------------
 
@@ -58,6 +64,13 @@
   , headerTableSize :: !Size
   -- | The max dynamic table size (defined in HPACK)
   , maxDynamicTableSize :: !Size
+  -- | The value informed by SETTINGS_HEADER_TABLE_SIZE.
+  --   If 'Nothing', dynamic table size update is not necessary.
+  --   Otherwise, dynamic table size update is sent
+  --   and this value should be set to 'Nothing'.
+  , limitForEncoding :: IORef (Maybe Size)
+  -- | The limit size of a dynamic table for decoding
+  , limitForDecoding :: !Size
   -- | Header to the index in Dynamic Table for encoder.
   --   Static Table is not included.
   --   Nothing for decoder.
@@ -95,8 +108,35 @@
 ----------------------------------------------------------------
 
 isDynamicTableEmpty :: DynamicTable -> Bool
-isDynamicTableEmpty hdrtbl = numOfEntries hdrtbl == 0
+isDynamicTableEmpty dyntbl = numOfEntries dyntbl == 0
 
+isSuitableSize :: Size -> DynamicTable -> Bool
+isSuitableSize siz tbl = siz <= limitForDecoding tbl
+
+data TableSizeAction = Keep | Change Size | Ignore Size
+
+needChangeTableSize :: DynamicTable -> IO TableSizeAction
+needChangeTableSize tbl = do
+    mlim <- getLimitForEncoding tbl
+    return $ case mlim of
+        Nothing          -> Keep
+        Just lim
+          | lim < maxsiz -> Change lim
+          | otherwise    -> Ignore maxsiz
+  where
+    maxsiz = maxDynamicTableSize tbl
+
+getLimitForEncoding :: DynamicTable -> IO (Maybe Size)
+getLimitForEncoding dyntbl = readIORef $ limitForEncoding dyntbl
+
+-- | When SETTINGS_HEADER_TABLE_SIZE is received from a peer,
+--   its value should be set by this function.
+setLimitForEncoding :: Size -> DynamicTable -> IO ()
+setLimitForEncoding siz dyntbl = writeIORef (limitForEncoding dyntbl) $ Just siz
+
+resetLimitForEncoding :: DynamicTable -> IO ()
+resetLimitForEncoding dyntbl = writeIORef (limitForEncoding dyntbl) Nothing
+
 ----------------------------------------------------------------
 
 -- Physical array index for Dynamic Table.
@@ -124,15 +164,16 @@
 
 -- | Creating 'DynamicTable'.
 newDynamicTableForEncoding :: Size -> IO DynamicTable
-newDynamicTableForEncoding maxsiz = newDynamicTable maxsiz (Just DHM.empty)
+newDynamicTableForEncoding maxsiz = newDynamicTable maxsiz maxsiz (Just DHM.empty)
 
 -- | Creating 'DynamicTable'.
 newDynamicTableForDecoding :: Size -> IO DynamicTable
-newDynamicTableForDecoding maxsiz = newDynamicTable maxsiz Nothing
+newDynamicTableForDecoding maxsiz = newDynamicTable maxsiz maxsiz Nothing
 
-newDynamicTable :: Size -> Maybe (DHM.DoubleHashMap HIndex) -> IO DynamicTable
-newDynamicTable maxsiz mhp = do
+newDynamicTable :: Size -> Size -> Maybe (DHM.DoubleHashMap HIndex) -> IO DynamicTable
+newDynamicTable maxsiz dlim mhp = do
     tbl <- newArray (0,end) dummyEntry
+    lim <- newIORef Nothing
     return DynamicTable {
         maxNumOfEntries = maxN
       , offset = end
@@ -140,6 +181,8 @@
       , circularTable = tbl
       , headerTableSize = 0
       , maxDynamicTableSize = maxsiz
+      , limitForEncoding = lim
+      , limitForDecoding = dlim
       , reverseIndex = mhp
       }
   where
@@ -148,16 +191,17 @@
 
 -- | Renewing 'DynamicTable' with necessary entries copied.
 renewDynamicTable :: Size -> DynamicTable -> IO DynamicTable
-renewDynamicTable maxsiz oldhdrtbl | shouldRenew oldhdrtbl maxsiz =
-    newDynamicTable maxsiz mhp >>= copyTable oldhdrtbl
+renewDynamicTable maxsiz olddyntbl | shouldRenew olddyntbl maxsiz =
+    newDynamicTable maxsiz dlim mhp >>= copyTable olddyntbl
   where
-    mhp = case reverseIndex oldhdrtbl of
+    dlim = limitForDecoding olddyntbl
+    mhp = case reverseIndex olddyntbl of
         Nothing -> Nothing
         _       -> Just DHM.empty
-renewDynamicTable _ oldhdrtbl = return oldhdrtbl
+renewDynamicTable _ olddyntbl = return olddyntbl
 
 copyTable :: DynamicTable -> DynamicTable -> IO DynamicTable
-copyTable oldhdrtbl newhdrtbl = getEntries oldhdrtbl >>= copyEntries newhdrtbl
+copyTable olddyntbl newdyntbl = getEntries olddyntbl >>= copyEntries newdyntbl
 
 getEntries :: DynamicTable -> IO [Entry]
 getEntries DynamicTable{..} = forM [1 .. numOfEntries] readTable
@@ -165,12 +209,12 @@
     readTable i = readArray circularTable $ adj maxNumOfEntries (offset + i)
 
 copyEntries :: DynamicTable -> [Entry] -> IO DynamicTable
-copyEntries hdrtbl                 [] = return hdrtbl
-copyEntries hdrtbl@DynamicTable{..} (e:es)
+copyEntries dyntbl                 [] = return dyntbl
+copyEntries dyntbl@DynamicTable{..} (e:es)
   | headerTableSize + entrySize e <= maxDynamicTableSize = do
-      hdrtbl' <- insertEnd e hdrtbl
-      copyEntries hdrtbl' es
-  | otherwise = return hdrtbl
+      dyntbl' <- insertEnd e dyntbl
+      copyEntries dyntbl' es
+  | otherwise = return dyntbl
 
 -- | Is the size of 'DynamicTable' really changed?
 shouldRenew :: DynamicTable -> Size -> Bool
@@ -183,17 +227,17 @@
 --   and a set of dropped OLD 'Index'
 --   are returned.
 insertEntry :: Entry -> DynamicTable -> IO DynamicTable
-insertEntry e hdrtbl = do
-    (hdrtbl', hs) <- insertFront e hdrtbl >>= adjustTableSize
-    let hdrtbl'' = case reverseIndex hdrtbl' of
-            Nothing  -> hdrtbl'
-            Just rev -> hdrtbl' { reverseIndex = Just (DHM.deleteList hs rev) }
-    return hdrtbl''
+insertEntry e dyntbl = do
+    (dyntbl', hs) <- insertFront e dyntbl >>= adjustTableSize
+    let dyntbl'' = case reverseIndex dyntbl' of
+            Nothing  -> dyntbl'
+            Just rev -> dyntbl' { reverseIndex = Just (DHM.deleteList hs rev) }
+    return dyntbl''
 
 insertFront :: Entry -> DynamicTable -> IO DynamicTable
-insertFront e hdrtbl@DynamicTable{..} = do
+insertFront e dyntbl@DynamicTable{..} = do
     writeArray circularTable i e
-    return $ hdrtbl {
+    return $ dyntbl {
         offset = offset'
       , numOfEntries = numOfEntries + 1
       , headerTableSize = headerTableSize'
@@ -208,21 +252,21 @@
         Just rev -> Just $ DHM.insert (entryHeader e) (HIndex i) rev
 
 adjustTableSize :: DynamicTable -> IO (DynamicTable, [Header])
-adjustTableSize hdrtbl = adjust hdrtbl []
+adjustTableSize dyntbl = adjust dyntbl []
 
 adjust :: DynamicTable -> [Header] -> IO (DynamicTable, [Header])
-adjust hdrtbl@DynamicTable{..} hs
-  | headerTableSize <= maxDynamicTableSize = return (hdrtbl, hs)
+adjust dyntbl@DynamicTable{..} hs
+  | headerTableSize <= maxDynamicTableSize = return (dyntbl, hs)
   | otherwise         = do
-      (hdrtbl', h) <- removeEnd hdrtbl
-      adjust hdrtbl' (h:hs)
+      (dyntbl', h) <- removeEnd dyntbl
+      adjust dyntbl' (h:hs)
 
 ----------------------------------------------------------------
 
 insertEnd :: Entry -> DynamicTable -> IO DynamicTable
-insertEnd e hdrtbl@DynamicTable{..} = do
+insertEnd e dyntbl@DynamicTable{..} = do
     writeArray circularTable i e
-    return $ hdrtbl {
+    return $ dyntbl {
         numOfEntries = numOfEntries + 1
       , headerTableSize = headerTableSize'
       , reverseIndex = reverseIndex'
@@ -237,17 +281,17 @@
 ----------------------------------------------------------------
 
 removeEnd :: DynamicTable -> IO (DynamicTable,Header)
-removeEnd hdrtbl@DynamicTable{..} = do
+removeEnd dyntbl@DynamicTable{..} = do
     let i = adj maxNumOfEntries (offset + numOfEntries)
     e <- readArray circularTable i
     writeArray circularTable i dummyEntry -- let the entry GCed
     let tsize = headerTableSize - entrySize e
         h = entryHeader e
-        hdrtbl' = hdrtbl {
+        dyntbl' = dyntbl {
             numOfEntries = numOfEntries - 1
           , headerTableSize = tsize
           }
-    return (hdrtbl', h)
+    return (dyntbl', h)
 
 ----------------------------------------------------------------
 
diff --git a/Network/HPACK/Types.hs b/Network/HPACK/Types.hs
--- a/Network/HPACK/Types.hs
+++ b/Network/HPACK/Types.hs
@@ -70,6 +70,7 @@
                  | TooLongEos -- ^ Eos of huffman string is more than 7 bits
                  | EmptyEncodedString -- ^ Encoded string has no length
                  | EmptyBlock -- ^ Header block is empty
+                 | TooLargeTableSize -- ^ A peer tried to change the dynamic table size over the limit
                  deriving (Eq,Show,Typeable)
 
 instance Exception DecodeError
diff --git a/Network/HTTP2.hs b/Network/HTTP2.hs
--- a/Network/HTTP2.hs
+++ b/Network/HTTP2.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 
--- | Framing in HTTP/2.
+-- | Framing in HTTP\/2(<https://tools.ietf.org/html/rfc7540>).
 module Network.HTTP2 (
   -- * Frame
     Frame(..)
@@ -91,7 +91,7 @@
 import Network.HTTP2.Encode
 import Network.HTTP2.Types
 
--- | The preface of HTTP/2.
+-- | The preface of HTTP\/2.
 --
 -- >>> connectionPreface
 -- "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
diff --git a/Network/HTTP2/RandomSkewHeap.hs b/Network/HTTP2/RandomSkewHeap.hs
--- a/Network/HTTP2/RandomSkewHeap.hs
+++ b/Network/HTTP2/RandomSkewHeap.hs
@@ -71,10 +71,13 @@
 gen = unsafePerformIO createSystemRandom
 {-# NOINLINE gen #-}
 
+{-
+main :: IO ()
 main = do
     let q = insert "c" 1 $ insert "b" 101 $ insert "a" 201 empty
     loop 1000 q
   where
+    loop :: Int -> Heap String -> IO ()
     loop 0 _ = return ()
     loop n q = do
         case uncons q of
@@ -82,3 +85,4 @@
             Just (x, w, q') -> do
                 putStrLn x
                 loop (n-1) (insert x w q')
+-}
diff --git a/http2.cabal b/http2.cabal
--- a/http2.cabal
+++ b/http2.cabal
@@ -1,5 +1,5 @@
 Name:                   http2
-Version:                1.0.4
+Version:                1.1.0
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
diff --git a/test-hpack/HPACKDecode.hs b/test-hpack/HPACKDecode.hs
--- a/test-hpack/HPACKDecode.hs
+++ b/test-hpack/HPACKDecode.hs
@@ -30,9 +30,9 @@
 
 run :: Bool -> Test -> IO Result
 run _ (Test _ [])        = return $ Pass
-run d (Test _ ccs@(c:_)) = do
-    let siz = maybe 4096 id $ size c
-    dhdrtbl <- newDynamicTableForDecoding siz
+run d (Test _ ccs) = do
+    -- 'size c' must not be used. Initial value is 4,096!
+    dhdrtbl <- newDynamicTableForDecoding 4096
     let conf = Conf { debug = d }
     testLoop conf ccs dhdrtbl
 
