diff --git a/Aws/Core.hs b/Aws/Core.hs
--- a/Aws/Core.hs
+++ b/Aws/Core.hs
@@ -486,6 +486,8 @@
 
       , HTTP.decompress = HTTP.alwaysDecompress
       , HTTP.checkStatus = \_ _ _ -> Nothing
+
+      , HTTP.redirectCount = 10
       }
     where
       checkDate f mb = maybe (f <$> mb) (const Nothing) $ lookup "date" sqOtherHeaders
diff --git a/Aws/S3/Commands/Multipart.hs b/Aws/S3/Commands/Multipart.hs
--- a/Aws/S3/Commands/Multipart.hs
+++ b/Aws/S3/Commands/Multipart.hs
@@ -131,12 +131,13 @@
   , upContentMD5 :: Maybe (Digest MD5)
   , upServerSideEncryption :: Maybe ServerSideEncryption
   , upRequestBody  :: HTTP.RequestBody
+  , upExpect100Continue :: Bool -- ^ Note: Requires http-client >= 0.4.10
 }
 
 uploadPart :: Bucket -> T.Text -> Integer -> T.Text -> HTTP.RequestBody -> UploadPart
 uploadPart bucket obj p i body =
   UploadPart obj bucket p i
-  Nothing Nothing Nothing body
+  Nothing Nothing Nothing body False
 
 data UploadPartResponse
   = UploadPartResponse {
@@ -162,7 +163,11 @@
                                , s3QAmzHeaders = map (second T.encodeUtf8) $ catMaybes [
                                    ("x-amz-server-side-encryption",) <$> writeServerSideEncryption <$> upServerSideEncryption
                                  ]
-                               , s3QOtherHeaders = []
+                               , s3QOtherHeaders = catMaybes [
+                                    if upExpect100Continue
+                                        then Just ("Expect", "100-continue")
+                                        else Nothing
+                                 ]
                                , s3QRequestBody = Just upRequestBody
                                }
 
diff --git a/Aws/S3/Commands/PutObject.hs b/Aws/S3/Commands/PutObject.hs
--- a/Aws/S3/Commands/PutObject.hs
+++ b/Aws/S3/Commands/PutObject.hs
@@ -34,7 +34,8 @@
   poRequestBody  :: HTTP.RequestBody (C.ResourceT IO),
 #endif
   poMetadata :: [(T.Text,T.Text)],
-  poAutoMakeBucket :: Bool -- ^ Internet Archive S3 nonstandard extension
+  poAutoMakeBucket :: Bool, -- ^ Internet Archive S3 nonstandard extension
+  poExpect100Continue :: Bool -- ^ Note: Requires http-client >= 0.4.10
 }
 
 #if MIN_VERSION_http_conduit(2, 0, 0)
@@ -42,7 +43,7 @@
 #else
 putObject :: Bucket -> T.Text -> HTTP.RequestBody (C.ResourceT IO) -> PutObject
 #endif
-putObject bucket obj body = PutObject obj bucket Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing body [] False
+putObject bucket obj body = PutObject obj bucket Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing body [] False False
 
 data PutObjectResponse
   = PutObjectResponse {
@@ -72,6 +73,9 @@
                                             , ("Cache-Control",) <$> poCacheControl
                                             , ("Content-Disposition",) <$> poContentDisposition
                                             , ("Content-Encoding",) <$> poContentEncoding
+                                            , if poExpect100Continue
+                                                  then Just ("Expect", "100-continue")
+                                                  else Nothing
                                             ]
                                , s3QRequestBody = Just poRequestBody
                                , s3QObject = Just $ T.encodeUtf8 poObjectName
diff --git a/Aws/S3/Core.hs b/Aws/S3/Core.hs
--- a/Aws/S3/Core.hs
+++ b/Aws/S3/Core.hs
@@ -115,6 +115,9 @@
       , s3ErrorHostId :: Maybe T.Text -- Error/HostId
       , s3ErrorAccessKeyId :: Maybe T.Text -- Error/AWSAccessKeyId
       , s3ErrorStringToSign :: Maybe B.ByteString -- Error/StringToSignBytes (hexadecimal encoding)
+      , s3ErrorBucket :: Maybe T.Text -- Error/Bucket
+      , s3ErrorEndpointRaw :: Maybe T.Text -- Error/Endpoint (i.e. correct bucket location)
+      , s3ErrorEndpoint :: Maybe B.ByteString -- Error/Endpoint without the bucket prefix
       }
     deriving (Show, Typeable)
 
@@ -245,7 +248,7 @@
       let m = S3Metadata { s3MAmzId2 = amzId2, s3MRequestId = requestId }
       liftIO $ tellMetadataRef metadata m
 
-      if HTTP.responseStatus resp >= HTTP.status400
+      if HTTP.responseStatus resp >= HTTP.status300
         then s3ErrorResponseConsumer resp
         else inner resp
 
@@ -269,6 +272,9 @@
                            let resource = listToMaybe $ root $/ elContent "Resource"
                                hostId = listToMaybe $ root $/ elContent "HostId"
                                accessKeyId = listToMaybe $ root $/ elContent "AWSAccessKeyId"
+                               bucket = listToMaybe $ root $/ elContent "Bucket"
+                               endpointRaw = listToMaybe $ root $/ elContent "Endpoint"
+                               endpoint = T.encodeUtf8 <$> (T.stripPrefix (fromMaybe "" bucket <> ".") =<< endpointRaw)
                                stringToSign = do unprocessed <- listToMaybe $ root $/ elCont "StringToSignBytes"
                                                  bytes <- mapM readHex2 $ words unprocessed
                                                  return $ B.pack bytes
@@ -280,6 +286,9 @@
                                       , s3ErrorHostId = hostId
                                       , s3ErrorAccessKeyId = accessKeyId
                                       , s3ErrorStringToSign = stringToSign
+                                      , s3ErrorBucket = bucket
+                                      , s3ErrorEndpointRaw = endpointRaw
+                                      , s3ErrorEndpoint = endpoint
                                       }
 
 type CanonicalUserId = T.Text
diff --git a/Aws/Sqs/Core.hs b/Aws/Sqs/Core.hs
--- a/Aws/Sqs/Core.hs
+++ b/Aws/Sqs/Core.hs
@@ -2,7 +2,7 @@
 module Aws.Sqs.Core where
 
 import           Aws.Core
-import           Aws.S3.Core                    (LocationConstraint, locationUsClassic, locationUsWest, locationUsWest2, locationApSouthEast, locationApNorthEast, locationEu)
+import           Aws.S3.Core                    (LocationConstraint, locationUsClassic, locationUsWest, locationUsWest2, locationApSouthEast, locationApSouthEast2, locationApNorthEast, locationEu)
 import qualified Blaze.ByteString.Builder       as Blaze
 import qualified Blaze.ByteString.Builder.Char8 as Blaze8
 import qualified Control.Exception              as C
@@ -142,6 +142,14 @@
         endpointHost = "ap-southeast-1.queue.amazonaws.com"
       , endpointDefaultLocationConstraint = locationApSouthEast
       , endpointAllowedLocationConstraints = [locationApSouthEast]
+      }
+
+sqsEndpointApSouthEast2 :: Endpoint
+sqsEndpointApSouthEast2
+    = Endpoint {
+        endpointHost = "sqs.ap-southeast-2.amazonaws.com"
+      , endpointDefaultLocationConstraint = locationApSouthEast2
+      , endpointAllowedLocationConstraints = [locationApSouthEast2]
       }
 
 sqsEndpointApNorthEast :: Endpoint
diff --git a/README.org b/README.org
--- a/README.org
+++ b/README.org
@@ -88,6 +88,12 @@
 
 * Release Notes
 
+** 0.12 series
+
+- 0.12
+  - S3: Support for "Expect: 100-continue" (optional, technically API breaking)
+  - S3: Properly treat errors with a "301 Permanent Redirect" as errors and expose endpoint information
+
 ** 0.11 series
 
 - 0.11.4
diff --git a/aws.cabal b/aws.cabal
--- a/aws.cabal
+++ b/aws.cabal
@@ -1,5 +1,5 @@
 Name:                aws
-Version:             0.11.4
+Version:             0.12
 Synopsis:            Amazon Web Services (AWS) for Haskell
 Description:         Bindings for Amazon Web Services (AWS), with the aim of supporting all AWS services. To see a high level overview of the library, see the README at <https://github.com/aristidb/aws/blob/master/README.org>.
 Homepage:            http://github.com/aristidb/aws
@@ -20,7 +20,7 @@
 Source-repository this
   type: git
   location: https://github.com/aristidb/aws.git
-  tag: 0.11.4
+  tag: 0.12
 
 Source-repository head
   type: git
