AWS API Gateway error response generates 502 "Bad Gateway"

26,370

Solution 1

If you throw an exception within the Lambda function (or context.fail), API Gateway reads it as if something had gone wrong with your backend and returns 502. If this is a runtime exception you expect and want to return a 500/404, use the context.succeed method with the status code you want and message:

if (parsed.error) {
  let error = {
    statusCode: 404,
    headers: { "Content-Type": "text/plain" } // not sure here
    body: new Error(parsed.error)
}
return context.succeed(error);

Solution 2

I had the same problem, in my case the issue was that my function was not returning anything in context.done(). So instead of context.done(null), I did context.done(null, {});

Solution 3

I've gotten 502's from multiple things. Here are the ones I have figured out so far.

Answer 1:

claudia generate-serverless-express-proxy --express-module {src/server?} If you are not using claudia and express, this answer won't help you.

Answer 2:

Lambda function->Basic Settings->Timeout. Increase it to something reasonable. It defaults to 3 seconds. But the first time building it typically takes longer.

Share:
26,370
johnny_mac
Author by

johnny_mac

Full Stack Javascript Developer with emphasis on back-end. Experience in Node, API, Database, AWS and CI/CD.

Updated on July 09, 2022

Comments

  • johnny_mac
    johnny_mac 3 months

    I have an API Gateway with a LAMBDA_PROXY Integration Request Type. Upon calling context.succeed in the Lambda, the response header is sent back with code 302 as expected (shown below). However, I want to handle 500 and 404 errors, and the only thing I am sure about so far, is that I am returning the error incorrectly as I am getting 502 Bad Gateway. What is wrong with my context.fail?

    Here is my handler.js

    const handler = (event, context) => { 
        //event consists of hard coded values right now
        getUrl(event.queryStringParameters)
        .then((result) => {
            const parsed = JSON.parse(result);
            let url;
            //handle error message returned in response
            if (parsed.error) {
                let error = {
                    statusCode: 404,
                    body: new Error(parsed.error)
                }
                return context.fail(error);
            } else {
                url = parsed.source || parsed.picture;
                return context.succeed({
                    statusCode: 302,
                    headers: {
                      Location : url
                    }
                  });
            }
        });
    };
    
  • Pablo Albaladejo
    Pablo Albaladejo about 1 year
    thanks a lot, @Michael, by default my lambda was configured with a 6 seconds timeout. Increasing the timeout solved de 502 response