'I get an ALB Lambda error - 502 Bad Gateway

I've been grappling with alb 2 lambda 502 bad gateway errors. In my ALB access logs, it shows a 'LambdaInvalidResponse' which i'm guessing is because my lambda returns an invalid response. This should be easily fixed but i can't for the life of me figure it out. Can someone help :).

In my python code i'm returning the following:

new_response = { "statusCode": 200, "statusDescription": "200 OK", "isBase64Encoded": False, "headers": { "Content-Type": "text/json; charset=utf-8" } }

new_response['body'] = '{"name":"function1"}'
return new_response

But it comes out like this in cloudwatch:

Returning response:

{'statusCode': '200', 'body': '{\n "message": "Success",\n "response": {\n "body": "{\"name\":\"function1\"}",\n "headers": {\n "Content-Type": "text/json; charset=utf-8"\n },\n "isBase64Encoded": false,\n "statusCode": 200,\n "statusDescription": "200 OK"\n }\n}'}

I'd really like to know why the result is getting wrapped up in the body - anyone got any ideas?



Solution 1:[1]

I'd really like to know why the result is getting wrapped up in the body - anyone got any ideas?

the body that you are looking at is from the request that cloudwatch received (wich contains informations about the event who trigged it. The request body of your lambda is just one of these informations), not from the body of your lambda itself (note that the body of your lambda is inside of the field response of the cloudwatch request wich is inside of the body key of the received cloudwatch request).

You are pretty close, but these lines are wrong:

"headers": { "Content-Type": "text/json; charset=utf-8" } }
new_response['body'] = '{"name":"function1"}'

if you wish to return a JSON on ALB lambda the proper way to do it should be:

    "headers": { "Content-Type": "application/json; charset=utf-8" } }
    new_response['body'] = json.dumps({"name":"function1"})

for example:

          import json

          def handler(event, context):
            msg = "Hello world from lambda!"
       
            response = {
                "statusCode": 200,
                "statusDescription": "200 OK",
                "isBase64Encoded": False,
                "headers": {
                    "Content-Type": "application/json"
                },
                "body": json.dumps({"myMsg": msg}) 
            }
            
            return response

If you check you cloudwatch logs, you're possibly receiving a LambdaUserError

if you wish to return a text instead of JSON, it should be something like:

 def handler(event, context):
        response = {
          "statusCode": 200,
          "statusDescription": "200 OK",
          "isBase64Encoded": False,
          "headers": {
            "Content-Type": "text/html"
           },
          "body": "<h1>Hello world from Lambda!</h1>"
        }
        return response

in that case, the Content-Type is text/html instead of application/json. And your body is formated as string/html instead of a json. :)

some usefull links:

https://docs.aws.amazon.com/lambda/latest/dg/services-alb.html

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html

Solution 2:[2]

In case returning JSON, Make sure you stringify it before return.

Python:

return {statusCode: 200, body: json.dumps({...}) }

JS:

return {statusCode: 200, JSON.stringify({...})

https://docs.aws.amazon.com/lambda/latest/dg/services-alb.html

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2