AWS Lambda
Python
Binary Data
Cloud Computing
Serverless Functions

How to return binary data from lambda function in AWS in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Returning binary data from a Python Lambda function is possible, but you cannot send raw bytes directly in the normal JSON response body. The usual pattern is to base64-encode the bytes, return the encoded string in body, and set isBase64Encoded to true. The gateway or integration layer then knows it should treat the response as binary content rather than plain text.

The Core Response Shape

When Lambda is fronted by API Gateway or a function URL using the usual HTTP-style event model, the response is a JSON object. That means the body itself must still be a string.

For binary output, the important fields are:

  • 'statusCode'
  • 'headers'
  • 'body'
  • 'isBase64Encoded'

A minimal example returning a PNG file:

python
1import base64
2
3
4def lambda_handler(event, context):
5    with open('/var/task/sample.png', 'rb') as f:
6        data = f.read()
7
8    return {
9        'statusCode': 200,
10        'headers': {
11            'Content-Type': 'image/png'
12        },
13        'body': base64.b64encode(data).decode('ascii'),
14        'isBase64Encoded': True
15    }

That is the core technique. The bytes are encoded as text for transport through the JSON response, and the integration layer decodes them for the HTTP client.

Why Base64 Is Required

Raw binary bytes are not valid JSON string content in the general case. Lambda proxy responses are JSON-shaped objects, so binary payloads must be encoded into a safe string representation.

Base64 increases payload size by roughly one third, so it is correct but not free. For large objects, direct S3 delivery or presigned URLs are often a better architecture than routing the whole binary through Lambda.

Headers Matter

Set the correct Content-Type so clients know how to interpret the content.

Examples:

  • 'image/png'
  • 'application/pdf'
  • 'application/octet-stream'

If you want the browser to download the file instead of displaying it inline, add Content-Disposition.

python
1'headers': {
2    'Content-Type': 'application/pdf',
3    'Content-Disposition': 'attachment; filename="report.pdf"'
4}

That makes the HTTP response behave more like a file download.

API Gateway Considerations

Historically, API Gateway configuration mattered a lot for binary support. In REST API setups, binary media types often needed to be configured so the gateway would treat responses for those content types correctly.

Even if the Lambda response is shaped correctly, a misconfigured gateway can still produce broken output, garbled content, or base64 text reaching the client unchanged.

So if the client receives something wrong, verify both:

  • the Lambda response includes isBase64Encoded: true
  • the gateway or front-end integration is configured to allow binary content for that media type

Returning Dynamically Generated Binary Data

You do not need a file on disk. The binary payload can be generated in memory.

Example with a ZIP payload:

python
1import base64
2import io
3import zipfile
4
5
6def lambda_handler(event, context):
7    buffer = io.BytesIO()
8    with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
9        zf.writestr('hello.txt', 'hello from lambda')
10
11    payload = buffer.getvalue()
12
13    return {
14        'statusCode': 200,
15        'headers': {
16            'Content-Type': 'application/zip',
17            'Content-Disposition': 'attachment; filename="bundle.zip"'
18        },
19        'body': base64.b64encode(payload).decode('ascii'),
20        'isBase64Encoded': True
21    }

This is useful for generated images, PDFs, archives, or other small binary responses.

When Not to Use Lambda for the Binary Payload

For large files, Lambda is often the wrong delivery path. A better design is:

  • generate or store the file in S3
  • return a presigned URL or redirect
  • let the client download directly from S3

That avoids base64 inflation, Lambda memory pressure, and API gateway payload limits.

Common Pitfalls

A common mistake is returning Python bytes directly in body. The body must be a string in the HTTP-style Lambda response shape.

Another mistake is base64-encoding the data but forgetting isBase64Encoded: true. Then the client may receive the encoded text literally.

People also often set the wrong Content-Type, which makes browsers or HTTP clients interpret the response incorrectly.

Finally, if API Gateway is in the path, check its binary handling rules. A correct Lambda response can still fail if the gateway is not configured consistently.

Summary

  • To return binary data from Lambda in Python, base64-encode the bytes and return them as the string body
  • Set isBase64Encoded to true so the integration treats the body as binary
  • Always send the correct Content-Type, and optionally Content-Disposition
  • API Gateway or other integrations may need matching binary-content configuration
  • This pattern is good for small binary responses generated or read inside Lambda
  • For large files, prefer S3 delivery or presigned URLs instead of sending the full payload through Lambda

Course illustration
Course illustration

All Rights Reserved.