I have created aws apigateway lambda integration for my proxy server. When i am making get request to the gateway, the request is successfully going through. The lambda function also executes successfully and writes response in outputstream with statusCode as 200. But apigateway always returns 502.
Snippet of handleRequest():
BufferedReader reader = new BufferedReader(new
InputStreamReader(inputStream));
JSONObject event = (JSONObject) parser.parse(reader);
request = Input.builder().setEvent(event).build();
Response response = requestManager.handleRequest(request);
logger.log(String.format("Response [%s]", response.toString()));
JSONObject responseJson = new JSONObject();
responseJson.put("statusCode", response.getStatusCode());
responseJson.put("headers", response.getHeaders());
JSONObject jsonBody = (JSONObject) parser.parse(response.getBody());
responseJson.put("body", jsonBody);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
logger.log("response recieved");
logger.log(String.format("responseJson [%s]", responseJson));
writer.write(responseJson.toJSONString());
writer.close();
logger.log(String.format("output stream [%s]", outputStream));
Am i missing anything ?
502 errors with Lambda usuaully indicate that you are using the Lambda proxy method and not generating the proper JSON response. Make sure your response adheres to the appropriate format.
If you are still having problems, please share a sample JSON generated by your Lambda function.
I had the same issue where all of my logs were saying the lambda executed successfully but API Gateway was still returning 502s on every request. Turns out I forgot to configure the response status codes in the API Gateway Console so it was throwing errors because the response was "incorrect" even with proper formatting. Just add in a status code 200, 400, 403, etc. to the route on your gateway and that might solve your problem.
Make sure you're hitting your callback with the response before calling context.succeed(event) or some other call to context.
This was my problem and putting my callback first fixed the persistent 502 res.
There are two versions of the response format. It might be that are posting a version 1 format response to an endpoint expecting version 2:
Lambda function response for format 1.0
With the 1.0 format version, Lambda integrations must return a response in the following format.
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"multiValueHeaders": { "headername": ["headervalue", "headervalue2", ...], ... },
"body": "..."
}
Lambda function response for format 2.0
With the 2.0 format version, API Gateway can infer the response format for you. API Gateway makes the following assumptions if your Lambda function returns valid JSON and doesn't return a statusCode:
isBase64Encoded is false.
statusCode is 200.
content-type is application/json.
body is the function's response.
The following examples show the output of a Lambda function and API Gateway's interpretation.
Lambda function output
API Gateway interpretation
"Hello from Lambda!"
{ "isBase64Encoded": false, "statusCode": 200, "body": "Hello from Lambda!", "headers": { "content-type": "application/json" }}
{ "message": "Hello from Lambda!" }
{ "isBase64Encoded": false, "statusCode": 200, "body": "{ \"message\": \"Hello from Lambda!\" }", "headers": { "content-type": "application/json" }}
To customize the response, your Lambda function should return a response with the following format:
{
"cookies" : ["cookie1", "cookie2"],
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"body": "Hello from Lambda!"
}
Related
My Spring Cloud Function(v3.1.6) based AWS Lambda function (without Lambda proxy integration) returns a list of data via API Gateway in the following format:
{
"isBase64Encoded": false,
"headers": {
"id": "<some_id>",
"contentType": "application/json",
"timestamp": "1644307568294"
},
"body": "{\"resultList\":[{\"id\":\"1\",\"name\":\"item\",(...some other fields...)}]}",
"statusCode": 200
}
My problem here is I want to return response.body in a JSON (ofc I've also created a Model schema) :
{
"resultList": [
{
"id": "1", "name": "item ",(...some other fields...)
}
]
}
I've configured an application/json based Response Template Mapping to transform the response to the desired format:
$util.parseJson($input.json('$.body'))
which returned that I wanted (check the attached image):
But when I call it via Postman, I've got this:
{
"message": "Internal server error"
}
and in CloudWatch I can see this logs:
2022-02-08T08:56:00.688+01:00 (...) Endpoint response body before transformations: [Binary Data]
2022-02-08T08:56:00.694+01:00 (...) Execution failed due to configuration error: Unable to transform response
What can be the problem?
I have a lambda (LAMBDA_PROXY) function with API gateway which is implemented in Golang (go-chi router).
when I invoke lambda from postman or browser, it gives 502 Bad Gateway status. In CloudWatch, I found following error message
Error while generating proxy response: Status code not set on response: errorString null
You need to respond with the correct response when using the "Use Lambda as Proxy" checkbox. Check out this document.
This may be more appropriate
The error you are getting is because, when you're using the API Gateway + Lambda proxy integration, the return value from the lambda function must be in the following JSON format:
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
Since you are using Golang, you can edit the return value of your main.go function by adding the following snippet as follows :
return events.APIGatewayProxyResponse{
Body: string(body),
StatusCode: 200
}, nil
Hope this helps!
I am new to AWS, I am getting {"message": "Internal server error"} while running the Lambda function with API Gateway in Postman.
I have checked the CloudWatchLogs, there is no error showing in the logs. But Postman returning {"message": "Internal server error"} this error.
It happens when you don't return the correct API Gateway format.
Try to return this in your Lambda:
def lambda_handler(event, context):
return {
"statusCode": 200,
"body": "{'Test': 'Test'}",
"headers": {
'Content-Type': 'text/html',
}
}
According to the log message you provide, it looks like the log from your Lambda function. I recommend you to enable logging feature on API Gateway side or you can use the test invoke feature on API Gateway console. They both are able to help you to debug your API.
Here is the common issues which might be able to help you diagnose the issue.
1. It doesn't have a right permission to allow API Gateway invoke your Lambda function.
2. It is set as AWS Service Proxy to your Lambda function, the response from your Lambda function doesn't return the response in the proper format.
Ref: https://forums.aws.amazon.com/thread.jspa?messageID=916452
The error can be caused by incorrect quotation marks.
A. Examples that produce the same error in Postman tests:
1. def lambda_handler(event, context):
return {
'statusCode': 200,
"body": {"one": 1000}
}
2. def lambda_handler(event, context):
return {
'statusCode': 200,
"body": "{"one": 1000}"
}
B. Examples that do not produce the error:
3. def lambda_handler(event, context):
return {
'statusCode': 200,
"body": "{'one': 1000}"
}
4. def lambda_handler(event, context):
return {
'statusCode': 200,
"body": '{"one": 1000}'
}
So, the type of quotation marks used after "body": is the reason for the error in this case. Note that while the Amazon lambda console does not produce an error for example 1., Postman says { "message": "Internal server error" }
Resolved it by adding isBase64EncodedFlag to my lambda response
results = {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(res),
"isBase64Encoded": False
}
I'm using AWS S3, API Gateway and Lambda function to resize my images on the fly. I keep having this error when the image doesn't exist:
Failed to load resource: the server responded with a status of 502 ()
It should return a 404 instead. Here the code in the lambda function:
S3.headObject({Bucket: BUCKET, Key: parameters.orignalImagePath}, function(err,data) {
if(err) {
console.log("[404] Image Not Found: " + parameters.orignalImagePath);
return callback(null, {
statusCode: '404',
body: '{ "message":"Image not found." }',
})
}
});
Here the logs from CloudWatch:
START
{"errorMessage":"The specified key does not exist.","errorType":"NoSuchKey"....}
[404] Image Not Found: Folder/image.png
END
Why i'm getting a 502 when my code return a 404. I checked the ApiGateway settings but couldn't find anything.
I found this: https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/
It might be because of the malformed response. I'm going to try with the updated response and the four fields.
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
UPDATE: It definitely helps to change the response with those 4 fields. However, the same request gets sometimes a 404 and sometimes a 502.
I'm writing a Lambda function that returns a response for Lambda Proxy Integration in Python. The API expects headers to be a dictionary.
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
This requires each header field to be unique, so there is no way to use multiple Set-Cookie's.
I've already tried to convert the dictionary to a list of tuples
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": [ ("headerName": "headerValue"), ... ],
"body": "..."
}
but API gateway complains Malformed Lambda proxy response.
Any idea how to set headers with the same name?
It is currently not possible to send multiple cookies with lambda integration.
If you send multiple set-cookie, then it will take the last one. ok, such a junk implementation right.
Reference, How can I send multiple Set-Cookie headers from API Gateway using a proxied Lambda
Let us see other avaialable options,
Lambda#Edge:
Here is what I find working with Lambda#Edge,
You can create a lambda function for viewer response and modify the header to set cookies.
'use strict';
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
const headers = response.headers;
// send via a single header and split it into multiple set cookie here.
headers['set-Cookie'] = 'cookie1';
headers['Set-Cookie'] = 'cookie2';
callback(null, response);
};
API Gateway Integration Request mapping:
Here is what I found and got working with integration request,
Hope it helps.
Lambda#Edge:
It is possible to set the headers this way:
response.headers['set-cookie'] = [
{ key: 'Set-Cookie', value: 'cookie1=value1' },
{ key: 'Set-Cookie', value: 'cookie2=value2' },
]
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-response
API Gateway:
Use multiValueHeaders:
response.multiValueHeaders = {
"Set-Cookie": [
'cookie1=value1',
'cookie1=value1'
]
}
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format