diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,9 @@
+## 1.0.6
+
+* Use `bracketOnError` when opening the network socket. Thanks to @purefn
+  for this improvement, which should stop `network-carbon` leaking file
+  descriptors when connections fail.
+
 ## 1.0.5
 
 * Correct the lower-bound of `bytestring` (introduced by @bergmark in 1.0.3)
diff --git a/network-carbon.cabal b/network-carbon.cabal
--- a/network-carbon.cabal
+++ b/network-carbon.cabal
@@ -1,5 +1,5 @@
 name: network-carbon
-version: 1.0.5
+version: 1.0.6
 synopsis: A Haskell implementation of the Carbon protocol (part of the Graphite monitoring tools)
 homepage: http://github.com/ocharles/network-carbon
 license: BSD3
diff --git a/src/Network/Carbon/Plaintext.hs b/src/Network/Carbon/Plaintext.hs
--- a/src/Network/Carbon/Plaintext.hs
+++ b/src/Network/Carbon/Plaintext.hs
@@ -17,6 +17,7 @@
   )
   where
 
+import Control.Exception (bracketOnError)
 import Control.Monad (unless)
 import Data.Monoid ((<>), mempty, mappend)
 import Data.Typeable (Typeable)
@@ -46,9 +47,10 @@
 -- | Connect to Carbon.
 connect :: Network.SockAddr -> IO Connection
 connect sockAddr = fmap Connection $ do
-  s <- Network.socket Network.AF_INET Network.Stream Network.defaultProtocol
-  Network.connect s sockAddr
-  return s
+  let openSocket = Network.socket Network.AF_INET Network.Stream Network.defaultProtocol
+  bracketOnError openSocket
+                 Network.close
+                 (\s -> fmap (const s) (Network.connect s sockAddr))
 
 
 --------------------------------------------------------------------------------
