AWS Lambda Base64 Encoded Request Body/Response Body

Table of Contents

In some case, the request body in lambda is base64 encoded string with isBase64Encoded flag. Most guides teach developer to decode the request body in lambda function. This post will discuss the root cause of this problem.

Some guides advice user set */* in binary media type in API gateway for handling all media type without warning including AWS documention. In API Gateway, the binary media types setting not only related to converting base64 string to binary in response. This setting also related to converting request body to base64 string.

Example repo

You can clone example repo and deploy to your AWS account to test the lambda function.

  • POST /input API logging the JSON stringified event object in CloudWatch Log, sending JSON or form-data but set the Content-Type request header to application/octet-stream or image/jpeg manually to see the base64 encoded request body. Sending JSON or form-data request without change Content-Type header to see normal request body.
  • GET /image API setting the Accept request header to image/jpeg to see the decoded image or */* to see the base64 encoded string.

Encoded request body

Encoded request body depends on two factors, binary media type in API gateway setting and Content-Type request header.
Binary media type I have added application/octet-stream and image/jpeg type in binary media type in API gateway.
If the Content-Type request header is application/octet-stream or image/jpeg, the request body will be encoded.
Otherwise, the request body is same as the request body from client.

Beware that common design of API server accepting json request body or form-data. If application/json or application/x-www-form-urlencoded type is added in binary media type in API gateway, the json request body or form-data will be encoded to base64 string even client is not sending file.

For the wildcard case like application/* in API gateway binary media type setting, API gateway will match the Content-Type request header start from application/.
So using application/* in binary media type setting will convert the request body with Content-Type header application/x-www-form-urlencoded, application/json, application/pdf, etc. to base64 string.

Using */* in API gateway binary media type setting means encoding any request body to base64 string since */* can match any Content-Type. So using */* in binary media type setting is highly not recommended.

PS. Missing Content-Type header in request look like API gateway will assume the request is JSON format and will use application/json for matching

Encoded response body

Converting base64 string to binary in response depends on two factors, binary media type in API gateway setting and Accept request header in client.
Binary media type I have added application/octet-stream and image/jpeg type in binary media type in API gateway.
If the first vaule of Accept request header is application/octet-stream or image/jpeg and the lambda payload contain isBase64Encoded true flag, the response body will be converted from base64 string to binary before returning to client.

For the wildcard case like application/* in API gateway binary media type setting, API gateway will match the Accept response header start from application/.
So using application/* in binary media type setting will convert base64 encoded response body to binary when Accept request header is set to application/json, application/pdf, etc. (Wildcard in API gateway setting)

But if we explicitly set type in API gateway binary media type setting like application/octet-stream but set Accept request header to wildcard application/*, the base64 string will not convert back to binary before sending out to client. (Wildcard in Accept request header)

When Accept request header accept multiple media type, API gateway only consider the first media type in header.
It means adding application/octet-stream in binary media type in API gateway but set Accept request header to application/*, application/octet-stream, the response body will keep in base64 string and not converting back to binary.

Posts in this Series