minio / minio-go

MinIO Go client SDK for S3 compatible object storage
https://docs.min.io/docs/golang-client-quickstart-guide.html
Apache License 2.0
2.5k stars 647 forks source link

The provided 'x-amz-content-sha256' header does not match what was computed. #1235

Closed zhucan closed 4 years ago

zhucan commented 4 years ago

My test case: package main

import ( "bytes" "fmt"

"github.com/minio/minio-go"

)

func main() { // Use a secure connection. ssl := false

// Initialize minio client object.
minioClient, err := minio.NewWithRegion("10.0.12.240:8060", "LGDUL089742B3WAGG3DL", "FilsJxgSOu3qFZlEHj16AC1xrCdSZCGCYn7ghwiF", ssl, "us-east-1")

if err != nil {
    fmt.Println(err)
    return
}
for i:=0; i<10;i++ {
    err := minioClient.MakeBucket(fmt.Sprintf("pvc-%d", i), "us-east-1")
    if err != nil {
        fmt.Println(err)
        continue
    }
    n, err := minioClient.PutObject("pvc-50932282-6de3-4f49-bcf3-095497fbb237", "csi-fs"+"/", bytes.NewReader([]byte("")), 0, minio.PutObjectOptions{})
    if err != nil {
        fmt.Println(err)
        continue
    }
    fmt.Println("Successfully uploaded bytes: ", n)
}

}

Result: image

Sometimes, It's failed.

harshavardhana commented 4 years ago

Incorrect usage of Go modules use import github.com/minio/minio-go/v6

zhucan commented 4 years ago

@harshavardhana I had updated the deps to v6, the new test case: package main

import ( "bytes" "fmt"

"github.com/minio/minio-go/v6"

)

func main() { // Use a secure connection. ssl := false

// Initialize minio client object.
minioClient, err := minio.NewWithRegion("10.0.76.240:8060", "LGDUL089742B3WAGG3DL", "FilsJxgSOu3qFZlEHj16AC1xrCdSZCGCYn7ghwiF", ssl, "us-east-1")

if err != nil {
    fmt.Println(err)
    return
}
for i:=0; i<10;i++ {
    err := minioClient.MakeBucket(fmt.Sprintf("pvc-%d", i), "us-east-1")
    if err != nil {
        fmt.Println(err)
        continue
    }
    n, err := minioClient.PutObject(fmt.Sprintf("pvc-%d", i), "csi-fs"+"/", bytes.NewReader([]byte("")), 0, minio.PutObjectOptions{})
    if err != nil {
        fmt.Println(err)
        continue
    }
    fmt.Println("Successfully uploaded bytes: ", n)
}

}

Result: image

harshavardhana commented 4 years ago

Ran this with AWS S3 no issues, looks like an issue Ceph server implementation

kannappanr commented 4 years ago
go run ~/test.go
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0
Successfully uploaded bytes:  0

With the following code

package main
import (
"bytes"
"fmt"

"github.com/minio/minio-go/v6"
)

func main() {
// Use a secure connection.
ssl := false

// Initialize minio client object.
minioClient, err := minio.NewWithRegion("play.min.io", "minio", "minio123", ssl, "us-east-1")

if err != nil {
    fmt.Println(err)
    return
}
for i:=0; i<10;i++ {
    err := minioClient.MakeBucket(fmt.Sprintf("pvc-%d", i), "us-east-1")
    if err != nil {
        fmt.Println(err)
        continue
    }
    n, err := minioClient.PutObject(fmt.Sprintf("pvc-%d", i), "csi-fs"+"/", bytes.NewReader([]byte("")), 0, minio.PutObjectOptions{})
    if err != nil {
        fmt.Println(err)
        continue
    }
    fmt.Println("Successfully uploaded bytes: ", n)
}
}

The backend can be returning error in the case of either MakeBucket or PutObject. You can add something extra when you print to distinguish which API is returning this error and debug further.

zhucan commented 4 years ago

@harshavardhana @koolhead17 Thanks,the errors was returned by the PutObject.

zhucan commented 4 years ago

@harshavardhana @kannappanr Take look at my new test case. package main

import ( "bytes" "fmt"

"github.com/minio/minio-go/v6"

)

func main() { // Use a secure connection. ssl := false

// Initialize minio client object.
minioClient, err := minio.NewWithRegion("10.0.76.240:8060", "LGDUL089742B3WAGG3DL", "FilsJxgSOu3qFZlEHj16AC1xrCdSZCGCYn7ghwiF", ssl, "us-east-1")

if err != nil {
    fmt.Println(err)
    return
}
for i:=0; i<10;i++ {
    err := minioClient.MakeBucket(fmt.Sprintf("pvc-%d", i), "us-east-1")
    if err != nil {
        fmt.Println(err)
        continue
    }
    n, err := minioClient.PutObject(fmt.Sprintf("pvc-%d", i), "csi-fs"+"/", bytes.NewReader([]byte("")), 0, minio.PutObjectOptions{})
    if err != nil {
        fmt.Println("put object + ", err)
        continue
    }
    fmt.Println("Successfully uploaded bytes: ", n)
}

}

With the following code: image

harshavardhana commented 4 years ago

@zhucan this is not our bug - this looks like a bug in ceph-rgw implementation

zhucan commented 4 years ago

@harshavardhana I had used s3cmd to test on it,but it's successful. image

image

harshavardhana commented 4 years ago

Notice you are creating a prefix / with 0bytes here, so it's not the same reproducer.

I shall close this issue for now, please report this to Ceph tracker.

lsw214 commented 4 years ago

@harshavardhana hello,v4 authentication can be used "Signed payload option" ?


`When transferring payload in a single chunk, you can optionally choose to include the payload hash in the signature calculations, referred as signed payload (if you don't include it, the payload is considered unsigned). The signing procedure discussed in the following section applies to both, but note the following differences:

Signed payload option – You include the payload hash when constructing the canonical request (that then becomes part of StringToSign, as explained in the signature calculation section). You also specify the same value as the x-amz-content-sha256 header value when sending the request to S3.

Unsigned payload option – You include the literal string UNSIGNED-PAYLOAD when constructing a canonical request, and set the same value as the x-amz-content-sha256 header value when sending the request to Amazon S3.

When you send your request to Amazon S3, the x-amz-content-sha256 header value informs Amazon S3 whether the payload is signed or not. Amazon S3 can then create signature accordingly for verification.`

harshavardhana commented 4 years ago

@harshavardhana hello,v4 authentication can be used "Signed payload option" ?


`When transferring payload in a single chunk, you can optionally choose to include the payload hash in the signature calculations, referred as signed payload (if you don't include it, the payload is considered unsigned). The signing procedure discussed in the following section applies to both, but note the following differences:

Signed payload option – You include the payload hash when constructing the canonical request (that then becomes part of StringToSign, as explained in the signature calculation section). You also specify the same value as the x-amz-content-sha256 header value when sending the request to S3.

Unsigned payload option – You include the literal string UNSIGNED-PAYLOAD when constructing a canonical request, and set the same value as the x-amz-content-sha256 header value when sending the request to Amazon S3.

When you send your request to Amazon S3, the x-amz-content-sha256 header value informs Amazon S3 whether the payload is signed or not. Amazon S3 can then create signature accordingly for verification.`

minio-go automatically does this @lsw214 https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html

bharath-krishna commented 5 months ago

Hi @harshavardhana I am also facing this kind of error when I added minio api url as backend in terraform configs. Here is the error,

Error writing state file: failed to upload state: operation error S3: PutObject, https response error StatusCode: 400, RequestID: 17D45EE7F4D481FB, HostID: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, api error XAmzContentSHA256Mismatch: The provided 'x-amz-content-sha256' header does not match what was computed.

zhucan commented 4 months ago

@harshavardhana

this is not our bug - this looks like a bug in ceph-rgw implementation

img_v3_02cc_5f63160d-edbe-4923-8ad1-2a17f2fc869g if the size of the object is zero, only disable it, can uploader the object with 0 size.

zhucan commented 4 months ago

/open