Blog

WordPress and S3 must be addressed using the specified endpoint

WordPress and S3 must be addressed using the specified endpoint

As I’ve gotten more familiar with both WordPress (running on EC2) and Amazon S3, I’ve started hosting a good part of my Web site assets on S3 (images, pdfs, etc.). It’s a CDN-ish way of keeping considerable load, and bandwidth, off my direct Web server(s).

For WordPress, there are a number of good plugins that help grease the wheels in terms of storing, and retrieving, content in S3. The most obvious content being that in my media library. With one particular plugin, I found that content was not being persisted to S3. Initial investigation made me think that is was a configuration error on my part, which is common. After enabling the usual WordPress debug flags, my debug.log file contained the following each time I tried to upload files:

Error uploading to S3: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint: “bucketname.s3.amazonaws.com”

According to Amazon, I should be able to reference my S3 bucket in this fashion. I’m using a simple PHP client (S3Client) that is provided, and well documented, by Amazon. After perusing through the APIs, there is a region option that can be provided to the underlying client. This got me thinking and I started digging more into the S3 docs…
Eventually, I stumbled across a key piece of S3 documentation:

Important
Amazon S3 supports virtual-hosted-style and path-style access in all Regions. The path-style syntax, however, requires that you use the region-specific endpoint when attempting to access a bucket. For example, if you have a bucket called mybucket that resides in the EU, you want to use path-style syntax, and the object is named puppy.jpg, the correct URI is http://s3-eu-west-1.amazonaws.com/mybucket/puppy.jpg. You will receive a “PermanentRedirect” error, an HTTP response code 301, and a message indicating what the correct URI is for your resource if you try to access a bucket outside the US Standard region with path-style syntax

Bingo! The trick is in the nomenclature for ‘US Standard.’ My S3 bucket is hosted in the Oregon region. Despite being in the United States, it’s technically outside of the ‘US Standard,’ which is on the East coast. Sure enough, as soon as provided the region (in my case: us-west-2) option to my PHP client (which in turn appends it to the request URL), all was well. This applies to anyone trying to do similar, hosted outside of the US Standard region.

Code-wise, my PHP fix ended up being how I initialize the S3 client, effectively changing:

$args = array(
'key' => $this->get_access_key_id(),
'secret' => $this->get_secret_access_key()
);

$this->client = Aws::factory( $args );

to:

$args = array(
'key' => $this->get_access_key_id(),
'secret' => $this->get_secret_access_key(),
'region' => $this->get_region()
);

$this->client = Aws::factory( $args );

Again, if you’re in the US Standard region (east US), you don’t need to provide this optional argument. If you’re in any other region, and want things to work, you’ll find that it’s not so optional 🙂

Here is a current list of AWS S3 regions and corresponding DNS names prefixes.

Leave Reply