Skip to content

Lambda@Edge Validation Error

1

I'm writing a Lambda@Edge function which is triggered by a CloudFront distribution on Origin Response. I want to catch some 404 errors and change them to 301 redirects. It works in testing but I get a 502 LambdaValidationError back from CloudFront when testing live. I've tried quite a few variations but can't figure out what is wrong.

Is there any way to get more information about what the error CloudFront is encountering or to validate the response before I return it?

Here's an example of the response I'm generating. I pass this back from the handler using callback(null, response). This version modifies the Recorsds[0].cf.response. I've also tried generating the response with just the status, statusDescription, and Location header.

{
  "headers": {
    "x-amz-request-id": [
      {
        "key": "x-amz-request-id",
        "value": "1234567890"
      }
    ],
    "x-amz-id-2": [
      {
        "key": "x-amz-id-2",
        "value": "1234567890="
      }
    ],
    "date": [
      {
        "key": "Date",
        "value": "Sat, 22 Feb 2025 17:59:00 GMT"
      }
    ],
    "server": [
      {
        "key": "Server",
        "value": "AmazonS3"
      }
    ],
    "location": [
      {
        "key": "Location",
        "value": "https://www.newsite.com/making-a-craft.html"
      }
    ]
  },
  "status": "301",
  "statusDescription": "Moved Permanently",
  "body": ""
}

This is generated by the following input in testing.

{
  "Records": [
    {
      "cf": {
        "response": {
          "headers": {
            "x-amz-request-id": [
              {
                "key": "x-amz-request-id",
                "value": "1234567890"
              }
            ],
            "x-amz-id-2": [
              {
                "key": "x-amz-id-2",
                "value": "1234567890="
              }
            ],
            "date": [
              {
                "key": "Date",
                "value": "Sat, 22 Feb 2025 17:59:00 GMT"
              }
            ],
            "server": [
              {
                "key": "Server",
                "value": "AmazonS3"
              }
            ],
            "content-type": [
              {
                "key": "Content-Type",
                "value": "application/xml"
              }
            ],
            "transfer-encoding": [
              {
                "key": "Transfer-Encoding",
                "value": "chunked"
              }
            ]
          },
          "status": "404",
          "statusDescription": "Not Found"
        },
        "request": {
          "clientIp": "::::",
          "headers": {
            "cloudfront-is-mobile-viewer": [
              {
                "key": "CloudFront-Is-Mobile-Viewer",
                "value": "false"
              }
            ],
            "cloudfront-is-tablet-viewer": [
              {
                "key": "CloudFront-Is-Tablet-Viewer",
                "value": "false"
              }
            ],
            "x-forwarded-for": [
              {
                "key": "X-Forwarded-For",
                "value": "::::"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "Amazon CloudFront"
              }
            ],
            "via": [
              {
                "key": "Via",
                "value": "2.0 1234567890.cloudfront.net (CloudFront)"
              }
            ],
            "origin": [
              {
                "key": "Origin",
                "value": "https://static.mysite.com:443/"
              }
            ],
            "host": [
              {
                "key": "Host",
                "value": "www-mysite.s3.us-west-2.amazonaws.com"
              }
            ]
          },
          "method": "HEAD",
          "origin": {
            "s3": {
              "authMethod": "none",
              "customHeaders": {},
              "domainName": "www-mysite.s3.us-west-2.amazonaws.com",
              "path": ""
            }
          },
          "querystring": "",
          "uri": "/old/making-a-craft.html"
        }
      }
    }
  ]
}
asked 10 months ago549 views
4 Answers
0

Did you publish a new version of the function after updating the code? You'll also need to update the CloudFront distribution to point to your new version. Just keep in mind that you can't create triggers for the $LATEST version.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-edit-function.html

AWS
EXPERT
answered 10 months ago
  • This hasn't been the problem but is definitely something I've struggled with as I've gotten my testing going.

    Upload new code, test against sample event, deploy to CloudFront, wait a couple minutes for propagation to edge, run live test, check in logs to ensure new version of Lambda code is running.

0

The HTTP 502 error you're encountering with the LambdaValidationError suggests that there's an issue with the response your Lambda@Edge function is generating. CloudFront is validating the response and finding it to be invalid. Here are a few things to consider:

  1. Response Structure: Ensure that your response object strictly adheres to the structure expected by CloudFront. The response should include status, statusDescription, headers, and body (even if empty).

  2. Header Format: Make sure all headers are in the correct format. Each header should be an array of objects, where each object has 'key' and 'value' properties.

  3. Status Code: Verify that the status code is a string, not a number.

  4. Read-only Headers: Be cautious about modifying read-only headers. Some headers like 'Transfer-Encoding' and 'Connection' cannot be modified.

  5. Body Size: If you're including a body, ensure it doesn't exceed the maximum size limit.

To get more information about the error:

  1. CloudWatch Logs: Enable CloudWatch Logs for your Lambda@Edge function. This can provide more detailed error messages and stack traces.

  2. Testing: Use the Lambda console to test your function with various inputs. This can help identify issues before deploying to CloudFront.

  3. Gradual Rollout: Consider using traffic control features in CloudFront to gradually roll out your changes, allowing you to monitor for errors without affecting all users.

To validate the response before returning it:

  1. Schema Validation: Implement a JSON schema validation in your Lambda function to ensure the response matches the expected structure before returning it.

  2. Use AWS Lambda Powertools: Consider using the Validation module from AWS Lambda Powertools for Python. It provides decorators and functions to validate both incoming and outgoing data against JSON schemas.

By implementing these suggestions and carefully reviewing your Lambda@Edge function's response structure, you should be able to resolve the validation error and successfully implement your 301 redirects.
Sources
Test and debug Lambda@Edge functions - Amazon CloudFront
HTTP 502 status code (Bad Gateway) - Amazon CloudFront
Validation - Powertools for AWS Lambda (Python)

answered 10 months ago
EXPERT
reviewed 10 months ago
0

I've found for a CloudFront Origin Response the only code that is working is to modify the response that was sent in. I get a validation error if any other headers in the response are modified or if I use a clean, minimal response.

(The error in the example I posted in the original question seems to be that the Content-Type header was cleared. Modifying any other headers can trigger a validation error.)

Working Code - Lambda@Edge with Origin Response Trigger:

'use strict';
export const handler = (event, context, callback) => {

    console.log('>>>',JSON.stringify(event));

    let request = event.Records[0].cf.request;
    let response = event.Records[0].cf.response;
    let headers = response.headers;

    if (request.uri == '/one.html') {
      // Body Description
      response.body = 'Minimal 301 Redirect, Modify Response';

      // Set new headers
      headers['location'] = [{key: 'Location', value: 'https://www.thriftyfun.com/two.html'}];

      // Set status and description
      response.status = '301';
      response.statusDescription = 'Moved Permanently';
     }

    console.log('<<<',JSON.stringify(response));

    // Return modified response
    callback(null, response);
};

Validation Error - - Lambda@Edge with Origin Response Trigger:

'use strict';
export const handler = (event, context, callback) => {

    console.log('>>>',JSON.stringify(event));

    let request = event.Records[0].cf.request;
    let response = event.Records[0].cf.response;

    if (request.uri == '/one.html') {
      // Return clean minimal response
      response = {
        body: 'Minimal 301 Redirect, Clean Response',
        headers: {
          location: [{
              key: 'Location',
              value: 'https://www.thriftyfun.com/two.html'
          }]
        },
        status: '301',
        statusDescription: 'Moved Permanently'
      };
     }

    console.log('<<<',JSON.stringify(response));

    // Return modified response
    callback(null, response);
};

My reading of the documentation, like this page, suggests that the latter code should work. And what's tricky is that it does work in other cases. I'm using minimal responses in CloudFront Functions. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-generating-http-responses.html#lambda-generating-http-responses-in-requests

answered 10 months ago
0

I’m using an Origin Request Lambda@Edge function to rewrite the incoming request URI based on a computed value. If that value ever contains an invalid character (for example, a space), CloudFront throws a LambdaValidationError as well. To troubleshoot, first enable CloudFront access logs (or real-time logs) for the distribution. That will let you see exactly what URI is being sent to Lambda and where it’s being rejected.

answered 4 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.