Home > Mobile >  Ruby AWS Lambda - 502 Bad Gateway from Application Load Balancer when returning binary content
Ruby AWS Lambda - 502 Bad Gateway from Application Load Balancer when returning binary content

Time:09-16

I have an AWS lambda (written in Ruby) that is functioning as a web server. I access the lambda through an application load balancer. The following code works well for html, javascript, and css files.

{ 
  statusCode: 200, 
  headers: {
    'Content-Type' => "text/html"
  },
  body: File.open("index.html").read
}

I have added code that attempts to return binary data from the Lambda.

{
  statusCode: 200,
  headers: {
    'Content-Type' => 'image/x-icon'
  },
  isBase64Encoded: true,
  body: Base64.encode64(IO.binread("favicon.ico"))
}

If I invoke the lambda through the load balancer, I receive a "502 Bad Gateway" response from the load balancer. The load balancer logs show the following.

"error_reason"="LambdaInvalidResponse" 

If I invoke the lambda from a command line with aws lambda invoke, I see my 200 response and the expected response data.

CodePudding user response:

Use Base64.strict_encode64 instead of Base64.encode64.

To find the problem, I spun up a Python lambda and made it return the exact same file. I verified that it worked with an ALB, and that the Ruby version did not. Then I used cli to invoke each one (tricky with the binary output), and compared.

Python’s default base64 encoder output the whole chunk without newlines, whereas Ruby's embedded newlines.

According to the Ruby docs:

  • strict_encode64 “complies with RFC 4648. No line feeds are added."
  • encode64 "complies with RFC 2045. Line feeds are added to every 60 encoded characters."

I guess the ALB is very picky about its Base-64 encoding!

  • Related