aws-sdk-go-v2 api error InvalidPart: One or more of the specified parts could not be found

183 Views Asked by At

So I tried to upload multiple part using AWS, but I got One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag. when doing CompleteMultipartUpload, anyone know which part that are not correct?

  • Even when I removed all ChecksumAlgorithm and ChecksumSHA256 part it still have the same error.
  • Even when I set ContentLength and used different size >5MB (so it gives different etag using strings.Repeat), it still give the same un-unseful error.

Normal put/get request without multipart works fine.

package main

import (
    "context"
    _ "embed"
    "encoding/json"
    "strings"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    "github.com/kokizzu/gotro/L"
)

//go:embed secret.json
var secret []byte

type Cfg struct {
    Url       string `json:"url"`
    AccessKey string `json:"accessKey"`
    SecretKey string `json:"secretKey"`
}

const helloWorld = "Hello world\n123\n"

func main() {
    var jsonCfg Cfg

    err := json.Unmarshal(secret, &jsonCfg)
    L.PanicIf(err, `secret.json parsing failed`)

    ctx := context.Background()
    cred := credentials.NewStaticCredentialsProvider(jsonCfg.AccessKey, jsonCfg.SecretKey, "")
    awsCfg, err := config.LoadDefaultConfig(ctx, config.WithCredentialsProvider(cred), config.WithRegion(`us-west-2`))
    L.PanicIf(err, `failed config.LoadDefaultConfig`)
    s3Client := s3.NewFromConfig(awsCfg)
    typ := types.ChecksumAlgorithmSha256

    {
        bucket := aws.String(`testbucket-054803077`)
        key := aws.String(`multipart` + string(typ))
        out, err := s3Client.CreateMultipartUpload(ctx, &s3.CreateMultipartUploadInput{
            Bucket:            bucket,
            Key:               key,
            ChecksumAlgorithm: typ, // not case sensitive
        })
        L.PanicIf(err, `failed s3Client.CreateMultipartUpload`)
        L.Describe(out)

        part, err := s3Client.UploadPart(ctx, &s3.UploadPartInput{
            Bucket:            bucket,
            Key:               key,
            UploadId:          out.UploadId,
            PartNumber:        2,
            ChecksumAlgorithm: typ,
            Body:              strings.NewReader(helloWorld),
        })
        L.PanicIf(err, `failed s3Client.UploadPart 1`)
        L.Describe(part)
        p1 := types.CompletedPart{
            ETag:       part.ETag,
            PartNumber: 1,
            //ChecksumCRC32:  part.ChecksumCRC32,
            //ChecksumCRC32C: part.ChecksumCRC32C,
            ChecksumSHA256: part.ChecksumSHA256,
            //ChecksumSHA1:   part.ChecksumSHA1,
        }

        part2, err := s3Client.UploadPart(ctx, &s3.UploadPartInput{
            Bucket:            bucket,
            Key:               key,
            UploadId:          out.UploadId,
            PartNumber:        2,
            ChecksumAlgorithm: typ,
            Body:              strings.NewReader(helloWorld),
        })
        L.PanicIf(err, `failed s3Client.UploadPart 2`)
        L.Describe(part2)
        p2 := types.CompletedPart{
            ETag:       part2.ETag,
            PartNumber: 2,
            //ChecksumCRC32:  part2.ChecksumCRC32,
            //ChecksumCRC32C: part2.ChecksumCRC32C,
            ChecksumSHA256: part2.ChecksumSHA256,
            //ChecksumSHA1:   part2.ChecksumSHA1,
        }

        final, err := s3Client.CompleteMultipartUpload(ctx, &s3.CompleteMultipartUploadInput{
            Bucket:   bucket,
            Key:      key,
            UploadId: out.UploadId,
            MultipartUpload: &types.CompletedMultipartUpload{
                Parts: []types.CompletedPart{
                    p1,
                    p2,
                },
            },
        })
        L.PanicIf(err, `failed s3Client.CompleteMultipartUpload`)
        L.Describe(final)
    }

}

the go mod file

module checksum1

go 1.20

require (
    github.com/aws/aws-sdk-go-v2/config v1.18.15
    github.com/aws/aws-sdk-go-v2/service/s3 v1.30.5
    github.com/kokizzu/gotro v1.2612.246
)

require (
    github.com/aws/aws-sdk-go-v2 v1.17.5 // indirect
    github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
    github.com/aws/aws-sdk-go-v2/credentials v1.13.15 // indirect
    github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.23 // indirect
    github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 // indirect
    github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 // indirect
    github.com/aws/aws-sdk-go-v2/internal/ini v1.3.30 // indirect
    github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.21 // indirect
    github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
    github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.24 // indirect
    github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23 // indirect
    github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.23 // indirect
    github.com/aws/aws-sdk-go-v2/service/sso v1.12.4 // indirect
    github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.4 // indirect
    github.com/aws/aws-sdk-go-v2/service/sts v1.18.5 // indirect
    github.com/aws/smithy-go v1.13.5 // indirect
    github.com/fatih/color v1.14.1 // indirect
    github.com/kr/pretty v0.3.1 // indirect
    github.com/kr/text v0.2.0 // indirect
    github.com/mattn/go-colorable v0.1.13 // indirect
    github.com/mattn/go-isatty v0.0.17 // indirect
    github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
    github.com/rogpeppe/go-internal v1.9.0 // indirect
    golang.org/x/sys v0.5.0 // indirect
)

the secret.json:

{ "url": "https://s3-us-west-2.amazonaws.com:443",
   "accessKey": "xxx",
   "secretKey": "xxx",
}

make sure the bucket already exists and writable.

1

There are 1 best solutions below

0
On

Nevermind PartNumber first part is typo, should be 1 not 2.

then the error will be api error EntityTooSmall: Your proposed upload is smaller than the minimum allowed size, so it should be >5MB