81

Created Lambda Hello world function using Node.js and created API GateWay trigger for Get call, tried the URL to access Lambda function, getting below error.

message: "Internal server error".

(very new to AWS)

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
user1671308
  • 859
  • 2
  • 8
  • 11
  • 2
    provide more details. and check https://aws.amazon.com/blogs/ai/integrate-your-amazon-lex-bot-with-any-messaging-service/ for details on how to correctly make api gateway and connect to lambda – sid8491 Dec 06 '17 at 10:55
  • Check CloudWatch to see the error. – Noel Llevares Dec 06 '17 at 12:09
  • Useful tips for debugging (from AWS): [Troubleshooting issues with HTTP API Lambda integrations](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-troubleshooting-lambda.html) – Henry Woody Mar 22 '22 at 04:13

14 Answers14

104

You need to pass the statusCode after executing the Lambda function. If you don't pass it the API Gateway will trigger an error 502 Bad Gateway by default.

message = {
   'message': 'Execution started successfully!'
}
return {
    'statusCode': 200,
    'headers': {'Content-Type': 'application/json'},
    'body': json.dumps(message)
}

EDIT: This sample is for Python. For node.js you just need to handle callback, the message is basically the same.

callback(null, {
    statusCode: 200,
    body: JSON.stringify(message),
    headers: {'Content-Type': 'application/json'}
});
ljmocic
  • 1,677
  • 2
  • 18
  • 23
  • 2
    check comments - https://github.com/aws-samples/aws-serverless-workshops/blob/master/WebApplication/3_ServerlessBackend/requestUnicorn.js The callback has to have a format – visrahane Jun 21 '18 at 19:18
  • I forgot to mention that this is for Python. Basically, the same thing is for node.js, you just need to handle the callback. – ljmocic Jul 03 '18 at 11:27
  • 2
    I ended up here with the same issue, but from the Node perspective. I needed to `JSON.stringify(message)` the body before passing it to APIGW. – ConorLuddy Oct 11 '18 at 09:52
  • 2
    Thanks for this, I had incorrectly set the property to `status`. Hope this helps someone else. – stephen mc Feb 26 '19 at 14:25
  • thanks a lot this was exactly my problem. Actually I should have stumbled over a how to which checking the documentation but i didn't... – Tobi Apr 13 '19 at 20:37
  • Thanks for this answer my dude. It's amazing how unintuitive all of this is, especially when going off of the Amazon guides themselves often lead to errors. – GhostBytes Aug 30 '19 at 21:57
  • It has been almost a year since I've answered this and the docs still didn't change. I'm glad that this was helpful to you! – ljmocic Aug 31 '19 at 11:05
  • 1
    Thank you for this answer. If you write a Lambda function from scratch, Amazon generates the return value with `status_code`. I don't understand why this is uninterpretable by API Gateway. At the very least, the error message should be more descriptive. Thanks again. – Josh Clark Feb 03 '23 at 09:37
40

Don't forget to click Deploy API under AWS API Gateway. Without it, change doesn't work.

enter image description here

ssuperczynski
  • 3,190
  • 3
  • 44
  • 61
10

For accessing dynamodb through lambda function from api gateway it needs:

  1. Create a role in AWS console that have access to dynamodb operations.

  2. Create a lambda function and assign the above created role to your lambda function.

  3. Create a api from API gateway in AWS management console and allow it to access to your lambda function.

  4. In order for your api to show a proper response the return type of lambda function should be a specific format i.e :

return {
  "statusCode": 200,
  "body": json.dumps(your response)
}
ssuperczynski
  • 3,190
  • 3
  • 44
  • 61
Shubham Pandey
  • 190
  • 2
  • 7
7

It's already explained above, but my problem was this worked for me with just calling the lambda:

exports.handler = async (event) => {
    return "gugus"
};

So all the tests in lambda were fine. The logs looked fine too. Just the API response was not ok.

To call it with the API gateway it needs something like this:

exports.handler = async (event) => {
...
    var res ={
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    };
    res.body = "gugus";
    return res;
};
Tobi
  • 1,702
  • 2
  • 23
  • 42
  • I had exactly the same issue: I was confident my lambda was ok because I could run it without errors. It happens, then, the lambdas can run with little restriction, but API Gateway expects an specific shape for the returned object. For what I figured out, it expects the following minimal interface (I used TypeScript to describe it): `{statusCode: number, body: string}`\ – Gerardo Lima Mar 01 '21 at 11:36
  • ... by the way I haven't found where theses constraints are declared, so if anyone knows and can share it would be great! – Gerardo Lima Mar 01 '21 at 11:37
  • It's not easy to discover, but https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html – scubbo Dec 18 '21 at 01:43
6

Be sure to pass the body across as a string in the response. If it's an object it will fail and give you the error you see. See here for more - http://www.awslessons.com/2017/lambda-api-gateway-internal-server-error/

Joel M.
  • 579
  • 5
  • 8
4

I had this problem using API Gateway + Lambda. In my case the problem was simply a permission issue. I was using stages in my API.

I had to execute

aws lambda add-permission --function-name X --source-arn "X" --principal apigateway.amazonaws.com --statement-id X --action lambda:InvokeFunction

Hope this helps.

miqrc
  • 1,964
  • 2
  • 18
  • 24
2

In my case the problem was that I created API Gateway from Lambda. In this case no method was created on the API Gateway side of REST API.

Fixed by going to API Gateway, create method manually (GET), attach Lambda function, and (!) Deploy changes.

After this link started to work.

2

When returning JSON body, added isBase65Encoded = False which solved it, this is actually happening when using Proxy Integration on API Gateway,

so this should work:

import json
return {
        “statusCode”: 200,
        “headers”:{‘Content-Type’: ‘application/json’},
        “body”: json.dumps(json_body),
        “isBase64Encoded”: False
    }
a.k
  • 1,035
  • 10
  • 27
1

I had this problem, but in my case I was using API Gateway and java lambda function. When looking in cloudwatch there was no error, every things look fine. The problem happen when API Gateway is attempting to render the response. In my case, I had in my response object, the statusCode which was not an int while API gateway need it to be a int.

This

    private final ResponseCode statusCode;
    private final String body;
    private final Map<String, String> headers;
    private final boolean isBase64Encoded;

After I change statusCode to int

    private final int statusCode;

This works

onlyme
  • 3,776
  • 2
  • 23
  • 17
1
callback(null, {
    statusCode: 200,
    body: JSON.stringify(message),
    headers: {'Content-Type': 'application/json'}
});

This worked for me perfectly

0

This error indicates that there was a problem with the configuration of the API. If you enable CloudWatch Logs you can see more information: https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/

jackko
  • 6,998
  • 26
  • 38
0

In my case spelling of headers is wrong, it was 'header' in place of 'headers' so make sure you have the right JSON response body.

akash maurya
  • 607
  • 9
  • 16
0

Sometimes CloudWatch logs nothing for this error. To see the error details go to the Lambdas page, click on the Test tab, and execute your function with a test event. You should see what CloudWatch isn't showing.

Bijou Trouvaille
  • 8,794
  • 4
  • 39
  • 42
0

Try increasing the function timeout. Configuration (Tab) -> General Configuration -> Edit -> Timeout

KISHORE K J
  • 186
  • 2
  • 4