Q:

Is there any way to specify a max number of retries when using s3cmd?

I've looked through the usage guide as well as the config docs and I'm just not seeing it. This is the output for my bash script that uses s3cmd sync when S3 appeared to be down:
WARNING: Retrying failed request: /some/bucket/path/
WARNING: 503 (Service Unavailable): 
WARNING: Waiting 3 sec...
WARNING: Retrying failed request: /some/bucket/path/
WARNING: 503 (Service Unavailable): 
WARNING: Waiting 6 sec...
ERROR: The read operation timed out

It looks like it is retrying twice using exponential backoffs, then failing. Surely there must be some way to explicitly state how many times s3cmd should retry a failed network call?

A:

I don't think you can the set the maximum retry count. I had a look at its source code on GitHub (https://github.com/s3tools/s3cmd/blob/master/S3/S3.py).
Looks like that value is 5 and hard-coded:
Line 240:
## Maximum attempts of re-issuing failed requests
_max_retries = 5

And the retry interval is calculated as:
Line 1004:
def _fail_wait(self, retries):
    # Wait a few seconds. The more it fails the more we wait.
    return (self._max_retries - retries + 1) * 3    

and the actual code that carries out the retries:
if response["status"] >= 500:
        e = S3Error(response)

        if response["status"] == 501:
            ## NotImplemented server error - no need to retry
            retries = 0

        if retries:
            warning(u"Retrying failed request: %s" % resource['uri'])
            warning(unicode(e))
            warning("Waiting %d sec..." % self._fail_wait(retries))
            time.sleep(self._fail_wait(retries))
            return self.send_request(request, retries - 1)
        else:
            raise e

So I think after the second try some other error occurred and it caused it to get out of the retry loop. 

