This topic provides answers to frequently asked questions about signatures when you use OSS.

Why is "The request signature we calculated does not match the signature you provided" displayed when OSS calculates a signature?

OSS allows you to include a signature in the Authorization header or in a URL. The following table lists the differences between the two methods.
Header URL
expires is not supported. expires is supported.
Methods: GET, POST, PUT, and DELETE. Methods: GET and PUT.
The date is in GMT. date is replaced with expires to specify timestamps.
Signatures are not URL-encoded. Signatures are URL-encoded.
"The request signature we calculated does not match the signature you provided" is displayed when OSS calculates a signature from the Authorization header or a URL. The following code provides an example on how to upload an object to OSS when you use the self-signed mode and call API operations:
#! /us/bin/envy python
#Author: hanli
#Update: 2018-09-29

from optparse import OptionParser
import urllib, urllib2
import datetime
import base64
import hmac
import sha
import os
import sys
import time

class Main():
  # Initial input parse

  def __init__(self,options):

    self.ak = options.ak =
    self.ed = options.ed
    self.bk = options.bk =
    self.oj = options.objects
    self.left = '\033[1;31;40m'
    self.right = '\033[0m'
    self.types = "application/x-www-form-urlencoded"    
    self.url = 'http://{0}.{1} /{2}'.format(self.bk,self.ed,self.oj)

  # Check client input parse

  def CheckParse(self):

    if (self.ak and and self.ed and self.bk and self.oj and != None:
      if str(self.ak and and self.ed and self.bk and self.oj and
      self.ConsoleLog("error","Input parameters cannot be empty")

  # GET local GMT time

  def GetGMT(self):
    SRM = datetime.datetime.utcnow()
    GMT = SRM.strftime('%a, %d %b %Y %H:%M:%S GMT')
    return GMT

  # GET Signature

  def GetSignature(self):

    mac ="{0}".format(,"PUT\n\n{0}\n{1}\n/{2}/{3}".format(self.types,self.GetGMT(),self.bk,self.oj), sha)
    Signature = base64.b64encode(mac.digest())
    return Signature

  # PutObject

  def PutObject(self):
      with open( as fd:
        files =
    except Exception as e:
      request = urllib2.Request(self.url, files)
      request.add_header('Host','{0}.{1} '.format(self.bk,self.ed))
      request.add_header('Authorization','OSS {0}:{1}'.format(self.ak,self.GetSignature()))
      request.get_method = lambda:'PUT'
      response = urllib2.urlopen(request,timeout=10)
    except Exception,e:
  # output error log

  def ConsoleLog(self,level=None,mess=None):

    if level == "error":
      sys.exit('\nHTTP/1.1 {0} OK\n{1}'.format(level,mess))

if __name__ == "__main__":

  parser = OptionParser()
  parser.add_option("-i",dest="ak",help="Must fill in Accesskey")
  parser.add_option("-k",dest="sk",help="Must fill in AccessKeySecrety")
  parser.add_option("-e",dest="ed",help="Must fill in endpoint")
  parser.add_option("-b",dest="bk",help="Must fill in bucket")
  parser.add_option("-o",dest="objects",help="File name uploaded to oss")
  parser.add_option("-f",dest="fi",help="Must fill localfile path")

  (options, args) = parser.parse_args()
  handler = Main(options)
Request headers:
PUT /yuntest HTTP/1.1
Accept-Encoding: identity
Content-Length: 147
Connection: close
User-Agent: Python-urllib/2.7
Date: Sat, 22 Sep 2018 04:36:52 GMT
Content-Type: application/x-www-form-urlencoded
Authorization: OSS B0g3mdt:lNCA4L0P43Ax
Response headers:
HTTP/1.1 200 OK
Server: AliyunOSS
Date: Sat, 22 Sep 2018 04:36:52 GMT
Content-Length: 0
Connection: close
x-oss-request-id: 5BA5C6E4059A3C2F
ETag: "D0CAA153941AAA1CBDA38AF"
x-oss-hash-crc64ecma: 8478734191999037841
Content-MD5: 0MqhU5QbIp3Ujqqhy9o4rw==
x-oss-server-time: 15
  • The parameters to sign are included in the Authorization header. The parameters for the header must be consistent with those for signatures. For more information about the header that carries the signature information, see Add a signature to the header.
  • When you use the PUT method, you can set Content-Type to application/x-www-form-urlencoded to calculate signatures.
  • You cannot set expires when you use the Authorization method to carry the signature information that authenticates requests. You can set expires only when you generate a signed URL by using OSS SDK or the OSS console.

What do I do if OSS returns a signature error when I use a WeChat mini program to send a request, but no signature errors occur when I use a browser?

The following figure shows the HTTP request captured when the request is sent using a browser.
  • The requests sent by the WeChat mini program and browser share the same URL, signature, and expires values. The difference is the request sent by the WeChat mini program contains Content-Type whereas the request sent by the browser does not.
  • Content-Type is not counted when OSS calculates the signature for the request that is sent by the browser, whereas Content-Type is counted when OSS calculates the signature for the request that is sent by the WeChat mini program. Consequently, the calculation results are different.

To resolve this problem, we recommend that you capture packets. If the request header includes Content-Type, Content-Type is counted when OSS calculates the signature.

What do I do if HTTP status code 403 is returned when the client uses an accelerated domain name to calculate a signature and sends a HEAD request?

Use tcpdump or Wireshar to capture packets. One possible cause is that when the client sends a HEAD request, a GET request is redirected to OSS using CDN. As a result, the signature calculated by the client is different from the signature that is calculated by OSS. To resolve this problem, upgrade Alibaba Cloud CDN.