0002-00000040

Updated at:

Problem description

When you use an Object Storage Service (OSS) API operation or software development kit (SDK), the "SignatureDoesNotMatch" error is returned.

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
  <RequestId>646DCB189AE2D1333018****</RequestId>
  <HostId>bucket.oss-cn-hangzhou.aliyuncs.com</HostId>
  <OSSAccessKeyId>LTAI****************</OSSAccessKeyId>
  <SignatureProvided>tPN3LTAI******** </SignatureProvided>
  <StringToSign>PUT\n\n\nTue, 23 May 2023 15:24:55 GMT\n/bucket/?acl</StringToSign>
  <StringToSignBytes>50 55 54 0A 0A 0A 54 75 65 2C 20 32 33 20 4D 61 79 20 32 30 32 33 20 31 35 3A 32 34 3A 35 35 20 47 4D 54 0A 2F 64 69 6E 61 72 79 2F 3F 61 63 6C </StringToSignBytes>
  <EC>0002-00000040</EC>
</Error>

Causes

When you call an API operation or use an OSS SDK to access OSS, the client must include a signature for the OSS server to perform identity authentication. If the server returns the preceding error message, the signature that you provided in the request is inconsistent with the signature calculated by the server. As a result, the request is rejected.

Sample problems

  • OSS returns a signature error for requests from a WeChat mini program, but not for requests from a browser.

  • The signed request is modified by a client proxy before it is sent to OSS. For example, a new header is added to the request.

  • When you use an accelerated domain name to send a HEAD request, CDN converts the HEAD request to a GET request by default.

    HEAD /ObjectName?objectMeta HTTP/1.1
    Host: your.cdn.com
    Date: Fri, 24 Feb 2012 06:38:30 GMT
    Authorization: OSS qn6q**************:77Dv****************
  • You configure the x-oss-range-behavior: standard request header in CDN to modify the range origin fetch behavior. OSS includes all request headers that have the x-oss- prefix in the signature calculation.

  • The Endpoint is a CNAME, but the CNAME option is not enabled during initialization.

    <?php
    if (is_file(__DIR__ . '/../autoload.php')) {
        require_once __DIR__ . '/../autoload.php';
    }
    if (is_file(__DIR__ . '/../vendor/autoload.php')) {
        require_once __DIR__ . '/../vendor/autoload.php';
    }
    
    use OSS\OssClient;
    use OSS\Core\OssException;
    $accessKeyId = getenv("OSS_ACCESS_KEY_ID");
    $accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
    $endpoint = "https://your.cname.com";
    
    try {
        // The Endpoint is a CNAME, but the CNAME option is not enabled during initialization.
        $isCNAME = false;
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, $isCNAME);
    } catch (OssException $e) {
        print $e->getMessage();
    }
  • The calculated signature contains a plus sign (+) and is not URL-encoded.

    GET /oss.jpg?OSSAccessKeyId=nz2p**********&Expires=1141889120&Signature=ab+cd HTTP/1.1
    Host: oss-example.oss-cn-hangzhou.aliyuncs.com
    Date: Fri, 24 Feb 2012 06:38:30 GMT

Solutions

If a signature error occurs, follow these steps to troubleshoot the issue.

  1. Verify that the AccessKey ID and AccessKey secret used for the signature are correct.

    You can log on to ossbrowser with your AccessKey ID and AccessKey secret to verify them. For more information, see ossbrowser 2.0 (Preview), a graphical management tool.

  2. Check whether the signature algorithm is valid.

    OSS provides two request methods that can include signatures. For more information, see Include signatures in the Authorization header and Add signatures to URLs. The following items describe the algorithms for the two signature methods:

    • Include signatures in the Authorization header

      StringToSign = VERB + "\n"
                    + Content-MD5 + "\n" 
                    + Content-Type + "\n" 
                    + Date + "\n" 
                    + CanonicalizedOSSHeaders
                    + CanonicalizedResource
      Signature = base64(hmac-sha1(AccessKeySecret, StringToSign)
    • Add signatures to URLs

      StringToSign = VERB + "\n" 
                    + CONTENT-MD5 + "\n" 
                    + CONTENT-TYPE + "\n" 
                    + EXPIRES + "\n" 
                    + CanonicalizedOSSHeaders
                    + CanonicalizedResource
      Signature = urlencode(base64(hmac-sha1(AccessKeySecret, StringToSign)))

    We recommend that you use OSS SDKs to access OSS. This eliminates the need to manually calculate the signature. For more information, see Overview.

  3. Check whether the value of the StringToSign field in the response body is consistent with that in the request.

    The StringToSign field specifies the string to be signed, which is the content that needs to be encrypted by using the AccessKey secret in the signature algorithm.

    Examples:

    PUT /bucket/abc?acl
    Date: Wed, 24 May 2023 02:12:30 GMT
    Authorization: OSS qn6q**************:77Dv****************
    x-oss-abc: mymeta

    The string to be signed calculated by using the preceding method:

    PUT\n\n\nWed, 24 May 2023 02:12:30 GMT\nx-oss-abc:mymeta\n/bucket/abc?acl
  4. After you identify the cause of the signature error, select the appropriate solution from the following table.

    Examples of signature error scenarios

    Solution

    OSS returns a signature error for requests from a WeChat mini program, but not for requests from a browser.

    See Step 3 and compare the StringToSign field in the response body. Check whether the request from the WeChat mini program includes an additional Content-Type field. If the request includes the Content-Type field, you must also include this field in the signature calculation.

    The client proxy modifies the signed request.

    See Step 3 and compare the StringToSign field in the response body with the string that your client signed to identify any differences.

    When you use an accelerated domain name to send a HEAD request, CDN converts the HEAD request to a GET request by default.

    • Use the default OSS domain name to send the HEAD request.

    • Configure a custom origin fetch header.

      By default, when a HEAD request passes through a CDN point of presence (POP) to the origin server, the request is automatically converted to a GET request. If you want the origin fetch request to remain a HEAD request, you can configure a custom origin fetch header. For more information, see Modify incoming request headers.

        • Custom parameter: Ali-Swift-Fwd-Head.

        • Value: on

        Important

        This operation affects the entire domain name. Use it with caution.

    CDN adds the x-oss-range-behavior: standard request header.

    When you send a request from the client, include the x-oss-range-behavior: standard request header in the signature calculation.

    The CNAME option is not enabled when you use a custom domain name to send a request to OSS.

    To enable the CNAME option using the OSS SDK for Java, set setSupportCname to true.

    For information about how to enable the CNAME option using SDKs for other programming languages, see SDK overview.

    The calculated signature in the signed URL contains a plus sign (+).

    URL-encode the signature before you send the request.

    GET /oss.jpg?OSSAccessKeyId=nz2p**********&Expires=1141889120&Signature=ab%2Bcd HTTP/1.1
    Host: oss-example.oss-cn-hangzhou.aliyuncs.com
    Date: Fri, 24 Feb 2012 06:38:30 GMT