diff --git a/Data/Conduit/Internal.hs b/Data/Conduit/Internal.hs
--- a/Data/Conduit/Internal.hs
+++ b/Data/Conduit/Internal.hs
@@ -326,7 +326,7 @@
     pipe' final left right =
         case right of
             Done r2 -> PipeM (final >> return (Done r2))
-            HaveOutput p c o -> HaveOutput (pipe' final left p) c o
+            HaveOutput p c o -> HaveOutput (pipe' final left p) (c >> final) o
             PipeM mp -> PipeM (liftM (pipe' final left) mp)
             Leftover _ i -> absurd i
             NeedInput rp rc -> upstream rp rc
@@ -357,7 +357,7 @@
     pipe' final left right =
         case right of
             Done r2 -> PipeM (final >> return (Done r2))
-            HaveOutput p c o -> HaveOutput (pipe' final left p) c o
+            HaveOutput p c o -> HaveOutput (pipe' final left p) (c >> final) o
             PipeM mp -> PipeM (liftM (pipe' final left) mp)
             Leftover right' i -> pipe' final (HaveOutput left final i) right'
             NeedInput rp rc ->
diff --git a/conduit.cabal b/conduit.cabal
--- a/conduit.cabal
+++ b/conduit.cabal
@@ -1,5 +1,5 @@
 Name:                conduit
-Version:             0.5.2.2
+Version:             0.5.2.3
 Synopsis:            Streaming data processing library.
 Description:
     @conduit@ is a solution to the streaming data problem, allowing for production, transformation, and consumption of streams of data in constant memory. It is an alternative to lazy I\/O which guarantees deterministic resource handling, and fits in the same general solution space as @enumerator@/@iteratee@ and @pipes@. For a brief tutorial, please see the "Data.Conduit" module.
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -26,6 +26,8 @@
 import Control.Monad.Trans.Resource (runExceptionT_, allocate, resourceForkIO)
 import Control.Concurrent (threadDelay, killThread)
 import Control.Monad.IO.Class (liftIO)
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.Writer (execWriter, tell)
 import Control.Applicative (pure, (<$>), (<*>))
 import Data.Functor.Identity (runIdentity)
 import Control.Monad (forever)
@@ -770,6 +772,19 @@
                     C.yield i
             res <- (src C.>+> C.injectLeftovers conduit) C.$$ CL.consume
             res `shouldBe` [1..10]
+    describe "up-upstream finalizers" $ do
+        let p1 = C.await >>= maybe (return ()) C.yield
+            p2 = idMsg "p2-final"
+            p3 = idMsg "p3-final"
+            idMsg msg = C.addCleanup (const $ tell [msg]) $ C.awaitForever C.yield
+            printer = C.awaitForever $ lift . tell . return . show
+            src = CL.sourceList [1 :: Int ..]
+        it "pipe" $ do
+            let run p = execWriter $ C.runPipe $ printer C.<+< p C.<+< src
+            run (p1 C.<+< (p2 C.<+< p3)) `shouldBe` run ((p1 C.<+< p2) C.<+< p3)
+        it "conduit" $ do
+            let run p = execWriter $ src C.$$ p C.=$ printer
+            run ((p3 C.=$= p2) C.=$= p1) `shouldBe` run (p3 C.=$= (p2 C.=$= p1))
 
 it' :: String -> IO () -> Spec
 it' = it
