PutObjects Cloudflare R2 Go

Hi so I recently set up the Cloudflare R2 for my project with Golang

func NewR2Service() (*S3Service, error) {
	s3Config := configs.LoadConfig()
	var bucket = s3Config.S3Bucket
	var accessKey = s3Config.CloudflareR2AccessId
	var secretKey = s3Config.CloudflareR2AccessKey

	r2Resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
		return aws.Endpoint{
			URL:           "<URL using Custom Domain R2>",
			SigningRegion: "auto",
		}, nil
	})

	cfg, err := config.LoadDefaultConfig(context.TODO(),
		config.WithEndpointResolverWithOptions(r2Resolver),
		config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
		config.WithRegion("apac"),
	)
	if err != nil {
		log.Fatal(err)
	}

	// Amazon S3 service client access key and so on
	s3Client := s3.NewFromConfig(cfg)

	return &S3Service{
		s3Client: s3Client,
		bucket:   bucket,
	}, nil
}

and this one is the function of UploadFile

func (s *S3Service) UploadFileToR2(ctx context.Context, key string, file []byte) error {
	input := &s3.PutObjectInput{
		Bucket:      aws.String(s.bucket), // Include the bucket name here
		Key:         aws.String(key),
		Body:        bytes.NewReader(file),
		ContentType: aws.String("image/jpeg"),
	}

	_, err := s.s3Client.PutObject(ctx, input)
	if err != nil {
		return err
	}

	return nil
}

The access key and secret key is valid. and I got response:

{
    "message": [
        "operation error S3: PutObject, https response error StatusCode: 401, RequestID: , HostID: , api error Unauthorized: Unauthorized"
    ],
    "success": false
}

is there anything I do before just putObject?

by the way, the custom domain I use is like {bucket}.domain.com so since the AWS SDK will return the bucket to the bucket.domain.com I put it like that but instead I got unauthorized