AWS S3 - CORS OPTIONS Preflight throwing 400 Bad Request during DELETE w/ VersionId

21,884

I just ran into this problem. It only occurs on Chrome. It was pretty awesome.

The solution is to add the following to your relevant <CORSRule> configuration in AWS:

<AllowedHeader>*</AllowedHeader>

That makes Chrome NOT send the OPTIONS request, and everything should work properly.

Share:
21,884

Related videos on Youtube

ThievingSix
Author by

ThievingSix

Updated on May 01, 2020

Comments

  • ThievingSix
    ThievingSix over 3 years

    I am attempting a deleteObject request for a delete marker using the Key of the object and the VersionID of the delete marker.

    Because of CORS, the browser (Chrome 34.0.1847.11) sends an OPTIONS preflight request to: http://bucket.s3-us-west-2.amazonaws.com/Folder/File.ext?versionId=0123456789

    Amazon S3 responds with 400 (Bad Request) with the following XML body:

    <?xml version="1.0" encoding="UTF-8"?>
    <Error>
        <Code>InvalidArgument</Code>
        <Message>This operation does not accept a version-id.</Message>
        <ArgumentValue>0123456789</ArgumentValue>
        <ArgumentName>versionId</ArgumentName>
        <RequestId>12345</RequestId>
        <HostId>1122334455</HostId>
    </Error>
    

    Because the XMLHttpRequest returns 400 (Bad Request), the DELETE request never gets executed. I am under the impression that AWS isn't handling the options request correctly. If there is a workaround, that would be great!

    My current CORS policy on the bucket is:

    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
        <CORSRule>
            <AllowedOrigin>*</AllowedOrigin>
            <AllowedMethod>HEAD</AllowedMethod>
            <AllowedMethod>GET</AllowedMethod>
            <AllowedMethod>PUT</AllowedMethod>
            <AllowedMethod>POST</AllowedMethod>
            <AllowedMethod>DELETE</AllowedMethod>
            <AllowedHeader>*</AllowedHeader>
        </CORSRule>
    </CORSConfiguration>
    

    FYI: I am using the AWS SDK for JS 2.0.0-rc10

    Thank you in advance.

    EDIT 1: I tried adding <AllowedMethod>OPTIONS</AllowedMethod> but Amazon returns Found unsupported HTTP method in CORS config. Unsupported method is OPTIONS

    EDIT 2:

    OPTIONS request/response headers:

    Remote Address: *********:443
    Request URL: https://bucket.s3-us-west-2.amazonaws.com/path/to/file_name?versionId=0123456789
    Request Method: OPTIONS
    Status Code: 400 Bad Request
    
    Request Headers
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-US,en;q=0.8
    Access-Control-Request-Headers: x-amz-user-agent, x-amz-security-token, x-amz-date, authorization, content-type
    Access-Control-Request-Method: DELETE
    Cache-Control: no-cache
    Connection: keep-alive
    DNT: 1
    Host: bucket.s3-us-west-2.amazonaws.com
    Origin: https://website.com
    Pragma: no-cache
    Referer: https://website.com/
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.60 Safari/537.36
    Query String Parameters
    versionId: 0123456789
    
    Response Headers
    Access-Control-Allow-Headers: x-amz-user-agent, x-amz-security-token, x-amz-date, authorization, content-type
    Access-Control-Allow-Methods: HEAD, GET, PUT, POST, DELETE
    Access-Control-Allow-Origin: *
    Connection: close
    Content-Type: application/xml
    Date: Tue, 18 Mar 2014 23:59:15 GMT
    Server: AmazonS3
    Transfer-Encoding: chunked
    Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
    x-amz-id-2: *************************
    x-amz-request-id: ***********
    

    The delete request doesn't ever actually happen because the OPTIONS fails.

    • Adam
      Adam over 9 years
      Please include all HTTP request and response headers for OPTIONS and DELETE requests. By the way, I've heard about issues with passing parameters for DELETE method. And just in case, try <AllowedMethod>OPTIONS</AllowedMethod> :)
    • ThievingSix
      ThievingSix over 9 years
      @Adam - Please see Edit 1 and Edit 2. Be aware that the library/browser never actually gets to call DELETE because the OPTIONS pre-flight fails. Normal deletes without the versionId GET parameter in the OPTIONS pre-flight work perfectly fine.
    • Adam
      Adam over 9 years
      According to the docs it should work. Try to pass the versionId parameter inside the request body (like with POST) instead of the query string. This way it won't be checked by the CORS rules, which does not mean it will work. You can also inspect the traffic on a lower level with a network sniffer (sometimes browsers lie).
    • ThievingSix
      ThievingSix over 9 years
      @Adam - I don't generate any of the requests myself and I believe the browser automatically generates the OPTIONS request when you do the DELETE request due to CORS. I am using Amazons SDK for this.
    • Adam
      Adam over 9 years
      Yes, the OPTIONS request is generated automatically and cannot be bypassed. I suppose the SDK creates the DELETE request for you, so you do not have much control, but you can always create a custom request using jQuery or pure XMLHttpRequest object. Also try with different browser. I also see the non-standard DNT header - try disabling the Do Not Track option for a while.
    • tkit
      tkit almost 7 years
      So did you manage to resolve this somehow perhaps? thnx
  • Alfonso Embid-Desmet
    Alfonso Embid-Desmet over 7 years
    As a comment, this configuration is set by going to your s3 bucket, clicking on Properties, Permissions, and Edit CORS Configuration
  • Dr Manhattan
    Dr Manhattan over 6 years
    I get 206 Partial Content
  • TheTC
    TheTC almost 5 years
    This didn't help. I wish it did.
  • Pedro Andrade
    Pedro Andrade over 4 years
    apparently there's some issue between chrome and s3 negotiating CORS. this answer explain it fully and give some alternatives: serverfault.com/a/856948
  • tymik
    tymik about 3 years
    @tmont I really doubt that CORS rules on S3 bucket make Chrome stop sending OPTIONS request, as Chrome is not aware about this rule in first place and OPTIONS is preflight method - it has to be executed always, according to my understanding of the mechanism.