Aws-sdk-go: The request signature we calculated does not match the signature you provided. Check your key and signing method.

Created on 5 May 2017  路  7Comments  路  Source: aws/aws-sdk-go

Version of AWS SDK for Go?

Latest

Version of Go (go version)?

go version go1.8 linux/amd64

What issue did you see?

When creating a PutObjectRequest like below it works fine I can PUT the file no problem. When I add
ACL: aws.String("public-read"), I get the error in the title, here is a sample of the url the GO sdk is generating.

https://<MY-BUCKET>.s3.eu-west-2.amazonaws.com/<MY-KEY>?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<AWS_ACCESS_KEY>/20170505/eu-west-2/s3/aws4_request&X-Amz-Date=20170505T793528Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host;x-amz-acl&X-Amz-Signature=2584062aaa76545665bfed7204fcf0dfe233a45016f698e7e8a11c34a5a7921e

I have tried with the root aws user and a normal user.
I have tried with bucket policy and without, and with bucket policy and IAM policy of FULL S3 access and without. Basically all combinations. Any time I add the ACL field the signature error appears.

I do not think that the url is being generated properly.

svc := s3.New(session.New(&aws.Config{Region: aws.String("eu-west-2")}))
    req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
        ACL: aws.String("public-read"),
        Bucket: aws.String("MY BUCKET NAME"),
        Key:    aws.String("MY KEY"),
    })
    str, err := req.Presign(15 * time.Minute)
service-api

Most helpful comment

@nextdimension - It looks like you have to set the header explicitly in the request.

package main                                                                                                               

import (                                                                                                                   
  "fmt"                                                                                                                    
  "net/http"                                                                                                               
  "time"                                                                                                                   

  "github.com/aws/aws-sdk-go/aws"                                                                                          
  "github.com/aws/aws-sdk-go/aws/session"                                                                                  
  "github.com/aws/aws-sdk-go/service/s3"                                                                                   
)                                                                                                                          

func main() {                                                                                                              
  svc := s3.New(session.New(&aws.Config{Region: aws.String("eu-west-2")}))                                                 
  req, _ := svc.PutObjectRequest(&s3.PutObjectInput{                                                                       
    ACL:    aws.String("public-read"),                                                                                     
    Bucket: aws.String("BUCKET"),                                                                                   
    Key:    aws.String("MY KEY"),                                                                                          
  })                                                                                                                       

  str, headers, _ := req.PresignRequest(15 * time.Minute)                                                                  
  httpreq, _ := http.NewRequest("PUT", str, nil)                                                                           
  for k, values := range headers {                                                                                         
    for _, value := range values {                                                                                         
      httpreq.Header.Add(k, value)                                                                                         
    }                                                                                                                      
  }                                                                                                                        
  fmt.Println(http.DefaultClient.Do(httpreq))                                                                              
}

If you have any additional issues, please let us know!

All 7 comments

Hello @nextdimension, thank you for reaching out to us. It looks like the Acl header is not being signed on the service's end. I am going to reach out to the service team and see why that is.

Oh, thank godness, theres an answer! I was going out of my mind :D Thanks.

@nextdimension - It looks like you have to set the header explicitly in the request.

package main                                                                                                               

import (                                                                                                                   
  "fmt"                                                                                                                    
  "net/http"                                                                                                               
  "time"                                                                                                                   

  "github.com/aws/aws-sdk-go/aws"                                                                                          
  "github.com/aws/aws-sdk-go/aws/session"                                                                                  
  "github.com/aws/aws-sdk-go/service/s3"                                                                                   
)                                                                                                                          

func main() {                                                                                                              
  svc := s3.New(session.New(&aws.Config{Region: aws.String("eu-west-2")}))                                                 
  req, _ := svc.PutObjectRequest(&s3.PutObjectInput{                                                                       
    ACL:    aws.String("public-read"),                                                                                     
    Bucket: aws.String("BUCKET"),                                                                                   
    Key:    aws.String("MY KEY"),                                                                                          
  })                                                                                                                       

  str, headers, _ := req.PresignRequest(15 * time.Minute)                                                                  
  httpreq, _ := http.NewRequest("PUT", str, nil)                                                                           
  for k, values := range headers {                                                                                         
    for _, value := range values {                                                                                         
      httpreq.Header.Add(k, value)                                                                                         
    }                                                                                                                      
  }                                                                                                                        
  fmt.Println(http.DefaultClient.Do(httpreq))                                                                              
}

If you have any additional issues, please let us know!

I am going to go ahead and close this issue. If you are still having issues, please reopen this.

@xibz
I used your final code snippet and am receiving a 403 Forbidden.
Any ideas?

Adding the headers worked for me. Thanks!

Figured it out... although I didn't need the 'public-read' ACL argument.

Needed to add non-zero httpreq.ContentLength for file.

Was this page helpful?
0 / 5 - 0 ratings