aws / aws-sdk-go-v2

AWS SDK for the Go programming language.
https://aws.github.io/aws-sdk-go-v2/docs/
Apache License 2.0
2.65k stars 638 forks source link

GetQueueUrl, https response error StatusCode: 400, RequestID: , deserialization failed, failed to decode response body, invalid character '<' looking for beginning of value #2451

Closed a-bhaskarank closed 9 months ago

a-bhaskarank commented 9 months ago

Describe the bug

Connecting docker sqs with the below endpoint resolver throwing GetQueueUrl, https response error StatusCode: 400, RequestID: , deserialization failed, failed to decode response body, invalid character '<' looking for beginning of value

docker run-cmd: docker run -p 9324:9324 -p 9325:9325 -vpwd/custom.conf:/opt/elasticmq.conf softwaremill/elasticmq

My Test code:

    package main

import (
    "context"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/sqs"
    "log"
)

func main() {
    getQUrl()
}
func getQUrl() {
    ctx := context.Background()
    qName := "input-queue"
    endpointOverride := "http://localhost:9324"
    region := "us-east-1"

    cfg, err := newConfig(endpointOverride, region)
    if err != nil {
        log.Panicln("error in sqs client creation", err)
    }
    client := sqs.NewFromConfig(*cfg)

    output, err := client.GetQueueUrl(ctx, &sqs.GetQueueUrlInput{QueueName: &qName})
    if err != nil || output.QueueUrl == nil {
        log.Panicf("unable to get url for the queue: %s. %v", qName, err)
    }
}
func newConfig(endpoint, region string) (*aws.Config, error) {
    cfg, err := config.LoadDefaultConfig(
        context.TODO(),
        config.WithRegion(region),
        config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(
            func(service, region string, options ...interface{}) (aws.Endpoint, error) {
                if (service == sqs.ServiceID) && len(endpoint) > 0 {
                    return aws.Endpoint{URL: endpoint, SigningRegion: region}, nil
                }
                return aws.Endpoint{}, &aws.EndpointNotFoundError{}
            },
        )),
    )

    return &cfg, err
}

Expected Behavior

It has to connect to the docker and get the queue url.

Current Behavior

Its throws error GetQueueUrl, https response error StatusCode: 400, RequestID: , deserialization failed, failed to decode response body, invalid character '<' looking for beginning of value

Its not only for GetQueueUrl even if I give the queue url and invoke sendMessage I get the same error for SendMessage call

Reproduction Steps

test code is given in the description

Possible Solution

No response

Additional Information/Context

The test code in the description section is able to connect to the AWS environment without issues., is there any issue with the EndpointResolverWithOptions?

AWS Go SDK V2 Module Versions Used

go 1.21.5

require (
    github.com/aws/aws-sdk-go-v2 v1.24.1
    github.com/aws/aws-sdk-go-v2/config v1.26.3
    github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7
)

require (
    github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect
    github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
    github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
    github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
    github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
    github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
    github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
    github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
    github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
    github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
    github.com/aws/smithy-go v1.19.0 // indirect
)

Compiler and Version used

go1.21.5 windows/amd64

Operating System and version

Windows 11

RanVaknin commented 9 months ago

Hi @a-bhaskarank ,

This error is indicating that the response received is not in a format that the SQS client can read. It's not clear what you are serving from that endpoint, but if I had to guess you are using some sort of SQS clone or local implementation.

Recently SQS migrated their service's protocol from the Query protocol which was XML based, to a JSONRPC protocol. My assumption is that the endpoint you are using is returning the data in the old protocol which is no longer supported.

You can verify this by enabling the response logs to view the raw response prior to deserialization by doing the following:

    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithClientLogMode(aws.LogResponseWithBody))

If you can provide the output here it will help us understand better what is happening. Thanks, Ran~

a-bhaskarank commented 9 months ago

Hi @RanVaknin , Thanks for the reply.,

Enabled response logs but the logs are not clear to me. However, your information about the query protocol helped to fix the issue. PFB the response logs:

<ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
      <Error>
        <Type>Sender</Type>
        <Code>MissingAction</Code>
        <Message>MissingAction; see the SQS docs.</Message>
        <Detail/>
      </Error>
      <RequestId>00000000-0000-0000-0000-000000000000</RequestId>
    </ErrorResponse>

FYI: I am running a local integration test(with a fake SQS in my local) for my application which sends messages to SQS. The fake/mock SQS docker image is here https://hub.docker.com/r/softwaremill/elasticmq.

The problem was resolved after pulling the latest docker image.

github-actions[bot] commented 9 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.