I was recently trying to move the assets to S3 for a Rails project. I decided to use the asset_sync gem which uploads assets to S3 on the pre-compilation of the assets. Everything worked smoothly for a few files but failed shortly for large asset files. It failed with 400 Bad Request with the message saying "IncompleteBody".
I took a look at the amazon S3 Error Responses page and it said that it happens when "You did not provide the number of bytes specified by the Content-Length HTTP header".
Generally, when a request is not sent with a 'Content-Length' header, it is usually because the request is sent as a chunked request. In a chunked request, the 'Content-Length' header is replaced with the 'Transfer-Encoding: chunked' header.
It appeared from the error that S3 wasn't able to handle the chunked request sent by Excon which is used by asset_sync gem internally. I did some digging and found out that Excon luckily provides a way to disable sending chunked requests. This can easily be done by setting 'nonblock' property to false. I added the following to my initializers:
And ta-da assets started uploading properly.
I hope this helps someone who is struggling to upload large assets using asset_sync gem and getting a 400 Bad Request error with an "IncompleteBody" message.