The statusDescription header must contain the status code and reason phrase, separated by a single space -- ALB returning 502 from Lambda
I've created a Lambda that check on a DynamoDB table the existence of a record matching host and request path and, if found, returns a redirect to the matching URL.
My Lambda returns this response but the ALB returns 502.
{
"statusCode": 301,
"statusDescription": null,
"headers": {
"Location": "https://www.my-target.co.uk/"
},
"multiValueHeaders": null,
"body": "Redirecting to https://www.my-target.co.uk/",
"isBase64Encoded": false
}
This is the log I find in CloudWatch for the Lambda function
START RequestId: 8b5a28f2-c56d-4418-a7b9-66ebe0ba2470 Version: $LATEST
[Information] EMG.ApplicationLoadBalancerRequestHandler: Received: GET /
[Information] EMG.ApplicationLoadBalancerRequestHandler: Processing: my-test.net /
[Information] EMG.RedirectManagers.RedirectTableRedirectManager: Fetching item: my-test.net / from table redirect-table
[Information] EMG.ApplicationLoadBalancerRequestHandler: Found: https://www.target.co.uk/ Permanent
END RequestId: 8b5a28f2-c56d-4418-a7b9-66ebe0ba2470
REPORT RequestId: 8b5a28f2-c56d-4418-a7b9-66ebe0ba2470 Duration: 69.59 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 39 MB
This is the response I get
HTTP/1.1 502
status: 502
Server: awselb/2.0
Date: Thu, 15 Aug 2019 19:13:58 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
I couldn't find anything saying we can't return non-200 responses from Lambda, so I really have no idea...
Hi @Kralizek, this probably isn't an issue with the .NET SDK, so I'm going to close out this issue. Please try reading some of our ALB troubleshooting documentation, asking a question on AWS Forums or Stack Overflow, or opening a Premium Support case.
Thanks @klaytaybai
For future desperate souls, you can find the same question on StackOverflow here: https://stackoverflow.com/questions/57562352/aws-alb-returning-502-from-lambda-instead-of-custom-http-status
Also, in the documentation it's clearly state that the statusDescription cannot be null and needs to contain the status and the reason separated by a space.
Here is the relevant documentation (emphasis mine): https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#respond-to-load-balancer
The response from your Lambda function must include the Base64 encoding status, status code, status description, and headers. You can omit the body. The statusDescription header must contain the status code and reason phrase, separated by a single space.
Should we change the StatusDescription property in ApplicationLoadBalancerResponse to compute a status description if it hasn't been set but StatusCode has been set?
That would be helpful, but where would you get the reason phrase from? I used ReasonPhrases.GetReasonPhrase(int) but I am not sure taking a dependency on Microsoft.AspNetCore.WebUtilities is worth it
I was thinking of something like this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ApplicationLoadBalancerResponse {StatusCode = 200 }.StatusDescription);
Console.WriteLine(new ApplicationLoadBalancerResponse { StatusCode = 404 }.StatusDescription);
Console.WriteLine(new ApplicationLoadBalancerResponse { StatusCode = 99999 }.StatusDescription);
}
}
public class ApplicationLoadBalancerResponse
{
public int StatusCode { get; set; }
string _statusDescription = null;
public string StatusDescription
{
get
{
if(this._statusDescription == null && this.StatusCode != 0)
{
var statusName = (System.Net.HttpStatusCode)this.StatusCode;
return $"{this.StatusCode} {statusName}";
}
return this._statusDescription;
}
set { this._statusDescription = value; }
}
}
This results in the following:
200 OK
404 NotFound
99999 99999
That looks pretty neat!
Also... On a sidenote, would it be possible to make the dictionary containing the headers use a case insensitive comparer? While working on converting a lambda from API Gateway to ALB, I took me a while to understand why I couldn't find the "Host" header (API Gateway), then I saw that ALB returns all headers in lower case (which is pretty peculiar, since I have always seen the headers be written in Pascal casing).
Reopening this as a feature request.
Thanks @Kralizek for pointing out the SO post. I just wanted to add that that in my testing with .net core lambda behind ALB, adding a space to the StatusDescription had no effect on the outcome of the 502. I had to add a header to get it to work.
public virtual async Task<ApplicationLoadBalancerResponse> ProcessRequest(ApplicationLoadBalancerRequest request, ILambdaContext context)
{
Console.WriteLine("Executing function...");
return await Task.FromResult( new ApplicationLoadBalancerResponse
{
StatusCode = 200,
StatusDescription = "OK",
Body = "all good",
Headers = new Dictionary<string, string>
{
{ "x-test", "1234" }
}
});
}
We have noticed this issue has not received attention in 1 year. We will close this issue for now. If you think this is in error, please feel free to comment and reopen the issue.
@ashishdhingra are issues labeled as feature request also subject to expiration?