Object storage systems like AWS S3 and Google Cloud Storage discuss the need to check the integrity of downloaded and uploaded objects, immediately after transfer, to ensure no corruption occurred.

For example, the [AWS CLI doc](https://docs.aws.amazon.com/cli/latest/topic/s3-faq.html) mentions:

> 
> **Upload:**
> The AWS CLI will calculate and auto-populate the Content-MD5 header for both standard and multipart uploads. If the checksum that S3 calculates does not match the Content-MD5 provided, S3 will not store the object and instead will return an error message back the AWS CLI.
> 
> 
> **Download:**
> The AWS CLI will attempt to verify the checksum of downloads when possible, based on the ETag header returned from a GetObject request that's performed whenever the AWS CLI downloads objects from S3. If the calculated MD5 checksum does not match the expected checksum, the file is deleted and the download is retried.
> 
> 
> 

Given that TCP incorporates automatic integrity checking, why do these systems require an additional checksum to verify integrity? It seems like by using TCP we should be able to ensure corruption did not occur in transfer.