diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,16 @@
+haskell-git-lfs (1.2.0) unstable; urgency=medium
+
+  * Avoid blindly copying over Content-Encoding and Transfer-Encoding
+    headers provided by the git-lfs server. This fixes interoperation
+    with gitlab's implementation of the git-lfs protocol, which sends
+    Transfer-Encoding chunked.
+  * uploadOperationRequests changed to provide a ServerSupportsChunks
+    value when constructing the RequestBody. This allows using 
+    Transfer-Encoding chunked when the server supports it.
+    (API change)
+
+ -- Joey Hess <id@joeyh.name>  Wed, 10 Nov 2021 13:52:11 -0400
+
 haskell-git-lfs (1.1.2) unstable; urgency=medium
 
   * Expand aeson bounds to allow 2.x
diff --git a/Network/GitLFS.hs b/Network/GitLFS.hs
--- a/Network/GitLFS.hs
+++ b/Network/GitLFS.hs
@@ -46,6 +46,7 @@
 	-- * Making transfers
 	downloadOperationRequest,
 	uploadOperationRequests,
+	ServerSupportsChunks(..),
 
 	-- * Endpoint discovery
 	Endpoint,
@@ -403,10 +404,10 @@
 
 -- | Builds a http request to perform a download.
 downloadOperationRequest :: DownloadOperation -> Maybe Request
-downloadOperationRequest = operationParamsRequest . download
+downloadOperationRequest = fmap fst . operationParamsRequest . download
 
 -- | Builds http request to perform an upload. The content to upload is
--- provided in the RequestBody, along with its SHA256 and size.
+-- provided, along with its SHA256 and size.
 --
 -- When the LFS server requested verification, there will be a second
 -- Request that does that; it should be run only after the upload has
@@ -414,8 +415,8 @@
 --
 -- When the LFS server already contains the object, an empty list may be
 -- returned.
-uploadOperationRequests :: UploadOperation -> RequestBody -> SHA256 -> Integer -> Maybe [Request]
-uploadOperationRequests op content oid size = 
+uploadOperationRequests :: UploadOperation -> (ServerSupportsChunks -> RequestBody) -> SHA256 -> Integer -> Maybe [Request]
+uploadOperationRequests op mkcontent oid size = 
 	case (mkdlreq, mkverifyreq) of
 		(Nothing, _) -> check Nothing
 		(Just dlreq, Nothing) -> check $ Just [dlreq]
@@ -432,25 +433,40 @@
 
 	mkdlreq = mkdlreq'
 		<$> operationParamsRequest (upload op)
-	mkdlreq' r = r
+	mkdlreq' (r, ssc) = r
 		{ method = "PUT"
-		, requestBody = content
+		, requestBody = mkcontent ssc
 		}
 	mkverifyreq = mkverifyreq'
 		<$> (operationParamsRequest =<< verify op)
-	mkverifyreq' r = addLfsJsonHeaders $ r
+	mkverifyreq' (r, _ssc) = addLfsJsonHeaders $ r
 		{ method = "POST"
 		, requestBody = RequestBodyLBS $ encode $
 			Verification oid size
 		}
 
-operationParamsRequest :: OperationParams -> Maybe Request
+-- | When the LFS server indicates that it supports Transfer-Encoding chunked,
+-- this will contain a true value, and the RequestBody provided to
+-- uploadOperationRequests may be created using RequestBodyStreamChunked.
+-- Otherwise, that should be avoided as the server may not support the
+-- chunked encoding.
+newtype ServerSupportsChunks = ServerSupportsChunks Bool
+
+operationParamsRequest :: OperationParams -> Maybe (Request, ServerSupportsChunks)
 operationParamsRequest ps = do
 	r <- parseRequest (T.unpack (href ps))
 	let headers = map convheader $ maybe [] M.toList (header ps)
-	return $ r { requestHeaders = headers }
+	let headers' = filter allowedheader headers
+	let ssc = ServerSupportsChunks $
+		any (== ("Transfer-Encoding", "chunked")) headers
+	return (r { requestHeaders = headers' }, ssc)
   where
 	convheader (k, v) = (CI.mk (E.encodeUtf8 k), E.encodeUtf8 v)
+	-- requestHeaders is not allowed to set Transfer-Encoding or 
+	-- Content-Length; copying those over blindly could request in a
+	-- malformed request.
+	allowedheader (k, _) = k /= "Transfer-Encoding"
+		&& k /= "Content-Length"
 
 type Url = T.Text
 
diff --git a/git-lfs.cabal b/git-lfs.cabal
--- a/git-lfs.cabal
+++ b/git-lfs.cabal
@@ -1,5 +1,5 @@
 Name: git-lfs
-Version: 1.1.2
+Version: 1.2.0
 Cabal-Version: >= 1.10
 License: AGPL-3
 Maintainer: Joey Hess <id@joeyh.name>
