amazon-web-servicesaws-lambdaaws-api-gatewayserverless-framework

502 "Internal Server Error" with API Gateway + Lambda when deploying


I'm using an API-Gateway + Lambda combo to process a POST request. I'm using Node + Serverless Framework.

When I run serverless offline, I am able to send a POST request and have my data stored on an S3. But when I deploy it and run the same POST request, I get a "502 Internal Server Error" message. Because it works locally but not in production, I'm pretty sure I have some permission/config problems.

    saveToS3(newData)
      .then(result => {
        callback(null, {
          statusCode: 200,
          headers: { 'Content-Type': 'application/json' },
          body: "Successfully added data!"
        });
      })
      .catch(e => callback(null, { statusCode: 500, body: JSON.stringify(e) }));

What I've checked:

What I haven't checked:

My yml:

service: myService

provider:
  name: aws
  runtime: nodejs12.x

  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:GetObject"
        - "s3:PutObject"
      Resource: "arn:aws:s3:::myS3Bucket/*"

functions:
  saveToS3:
    handler: handler.saveToS3
    events:
      - http:
          path: users
          method: post
          cors: true
plugins:
  - serverless-offline

resources:
 Resources:
   NewResource:
     Type: AWS::S3::Bucket
     Properties:
       BucketName: myS3Bucket

Solution

  • Found the issue, facepalming because it took me hours to find it.

    I had two problems:

    Helpful links: - https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format - (if you're using serverless framework) https://github.com/dherault/serverless-offline/issues/405

    If using API Gateway, make sure your lambda function's response looks like the code snippet below. Otherwise it will throw a "502 - Malformed Lambda Function" error.

    {
        "isBase64Encoded": true|false,
        "statusCode": httpStatusCode,
        "headers": { "headerName": "headerValue", ... },
        "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
        "body": "..."
    }