In CloudFront’s defence:
Understand this that CloudFront pulls from CDN. Now the data that is being fetched from original server is uncached and this fetching happens in real time. So there won’t be any replication delays. CloudFront doesn't know about the content until it receives requests for it. So, all it does is fetch request from origin server, and cache it as appropriate, for serving subsequent requests.
Now what could be the problem?
This issue at hand may have to do something with "negative caching" – Now here a request wont work if it is typically done to avoid hammering the origin of whatever's being cached with requests that are likely to fail anyway.
Okay this is what happens normally:
By default, when your origin returns an HTTP 4xx or 5xx status code, CloudFront caches these error responses for five minutes and then submits the next request for the object to your origin to see whether the problem that caused the error has been resolved and the requested object is now available. Refer the link for more info:
Now if you try to download the file from that particular CloudFront edge before the upload into S3 is complete, S3 will return an error, and CloudFront -- at that edge location -- will cache that error and remember, for the next 5 minutes. So this is where if another request comes there could be trouble:
You can fix this though:
Specify the error-caching duration that is the Error Caching Minimum TTL—for each 4xx and 5xx status code that CloudFront caches.
Refer this if needed
Configuring Error Response Behavior.
I hope this helps