title: Lambda: Amazon s3 direct upload error signature does not match
body: <p>I want to upload image files to AWS s3 bucket by using pre-signed URLs, But I'm getting an error shown in the screen shot, I've followed the post from this page <a href="https://www.netlify.com/blog/2016/11/17/serverless-file-uploads/" rel="nofollow noreferrer">s3 direct file upload</a>, I would like to know what mistake I'm making and also I want to know whether this is server side issue or there should I use some different approach for making put request to 'pre-signed' URL, thanks ahead.</p>
  
  <p><a href="https://i.stack.imgur.com/F9nWH.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/F9nWH.png" alt="Error I&#39;m Getting on Postman"></a></p>
  
  <p>My serverless.yml</p>
  
  <pre><code>service: my-service-api
  
  provider:
    name: aws
    runtime: nodejs4.3
    stage:  dev
    region: us-east-1
    iamRoleStatements:
      - Effect: "Allow"
        Action:
          - "dynamodb:*"        
        Resource: "*"
      - Effect: "Allow"
        Action:
          - "s3:*"        
        Resource: "arn:aws:s3:::profile-images/*"   
  
  custom:
    globalResultTtlInSeconds: 1
  
  package:
    individually: true
    include:
      - node_modules/mysql/**
      - node_modules/bluebird/**
      - node_modules/joi/**
    exclude:
      - .git/**
      - .bin/**
      - tmp/**
      - api/**
      - node_modules/**
      - utils/**
      - package.json
      - npm_link.sh
      - templates.yml
  
  functions:
    profiles:
      handler: api/profiles/handler.profiles
      events:
        - http:
            method: POST
            path: api/profiles/uploadURL
            cors: true
            integration: lambda
            request: ${file(./templates.yml):request}  
            authorizer: 
              arn: arn:aws:lambda:us-east-1:000000000000:function:customAuthorizer
              resultTtlInSeconds: ${self:custom.globalResultTtlInSeconds}
              identitySource: method.request.header.Authorization
      package:
        include:
          - api/profiles/**
          - node_modules/node-uuid/**
          - node_modules/jsonwebtoken/**
          - node_modules/rand-token/**          
  
  resources:
    Resources:
      UploadBucket:
        Type: AWS::S3::Bucket
        Properties:
          BucketName: profile-images
          AccessControl: PublicRead
          CorsConfiguration:
            CorsRules:
            - AllowedMethods:
              - GET
              - PUT
              - POST
              - HEAD
              AllowedOrigins:
              - "*"
              AllowedHeaders:
              - "*"   
      IamPolicyInvokeLambdaFunction:
        Type: AWS::IAM::Policy     
        Properties: 
          PolicyName: "lambda-invoke-function"
          Roles:
            - {"Ref" : "IamRoleLambdaExecution"}
          PolicyDocument:
            Version: '2012-10-17'
            Statement:            
                - Effect: Allow
                  Action: 
                    - "lambda:InvokeFunction"
                  Resource: "*"
  </code></pre>
  
  <p>My handler file</p>
  
  <pre><code>var s3Params = {
                  Bucket: 'profile-images',
                  Key: image.name,
                  ACL: 'public-read'
              };
  
   s3.getSignedUrl('putObject', s3Params, function (err, url){
         if(err){
            console.log('presignedURL err:',err);
            context.succeed({error: err});
         }
         else{
            console.log('presignedURL: ',url);
            context.succeed({uploadURL: url});                                           
         }                    
    });
  </code></pre>