AWS Lambda Error – Unable to marshal response
By logging the raw return value, enforcing JSON-safe structures, removing non-serializable types, and ensuring a correct API Gateway response shape, you restore stable, predictable Lambda behavior.
Problem
Your Lambda completes execution, but AWS reports:
Runtime.MarshalError: Unable to marshal response
This means Lambda could not convert your handler’s return value into the required wire format.
Possible causes:
- Handler returned a type Lambda cannot serialize (e.g., a class instance or circular reference)
- Response is not valid JSON when using API Gateway proxy mode
- Handler returned an unexpected structure or returned nothing at all
Clarifying the Issue
Lambda always attempts to serialize your return value into JSON (Node.js/Python) unless you explicitly write to stdout via the Runtime API. If the object cannot be serialized, or is not the format AWS expects, marshalling fails before the response ever leaves Lambda.
Key failure modes:
- Returning non-JSON-safe objects (Date, Map, Set, Decimal, custom classes)
- Returning Python objects that contain unserializable types
- Returning undefined, None, or an empty return in frameworks expecting structured output
Why It Matters
An invalid response structure silently breaks API workflows and causes confusing 502/504 errors at API Gateway, ALB, or Step Functions.
Impact:
- API Gateway will reject malformed responses with “Internal Server Error”
- Step Functions will surface the error as a task failure with no helpful detail
- Downstream systems receive no usable payload, triggering retries and noise
Key Terms
- Marshalling – Converting your handler return value into JSON for transport
- Proxy integration – API Gateway mode requiring
{ statusCode, headers, body } - Serializable type – Values that JSON.stringify/json.dumps can safely encode
Steps at a Glance
- Confirm the marshalling error in CloudWatch
- Log the raw handler return value
- Validate response structure
- Remove unserializable types
- Ensure API Gateway proxy mode structure is correct
- Add explicit JSON serialization
- Re-test with a controlled invocation
Detailed Steps
Step 1: Confirm the marshalling error in CloudWatch
Retrieve recent logs:
aws logs tail /aws/lambda/my-function --since 5m
You should see: Unable to marshal response.
Now determine what the handler actually returned.
Step 2: Log the raw handler return value
Add a diagnostic log inside the handler.
Node.js example:
exports.handler = async () => {
const result = getData();
console.log("RETURN VALUE:", result);
return result;
};
This shows you the exact object Lambda is attempting to serialize.
Next, validate the structure.
Step 3: Validate response structure
For API Gateway proxy integrations, the return value must be:
{
"statusCode": 200,
"headers": { "Content-Type": "application/json" },
"body": "{\"ok\":true}"
}
Anything else will fail marshaling or be rejected by API Gateway.
Move on to identifying bad types.
Step 4: Remove unserializable types
If your data includes Maps, Sets, Dates, Decimals, or custom classes, convert them.
Node.js example:
return {
ok: true,
now: new Date().toISOString(), // Date is now safely serializable
items: Array.from(mySet), // Set → Array
};
Python example:
return {
"ok": True,
"time": datetime.utcnow().isoformat(), # datetime → string
"items": list(my_set), # set → list
}
After normalizing types, enforce explicit JSON formatting.
Step 5: Ensure API Gateway proxy mode structure
If using proxy mode, the body must be a string.
Node.js:
return {
statusCode: 200,
body: JSON.stringify({ ok: true })
};
Python:
return {
"statusCode": 200,
"body": json.dumps({"ok": True})
}
Now force serialization directly.
Step 6: Add explicit JSON serialization
This ensures your response is always marshal-safe.
Node.js:
return JSON.parse(JSON.stringify(result));
Python:
return json.loads(json.dumps(result))
If this passes, your original object contained an unserializable value.
Now verify behavior end-to-end.
Step 7: Re-test with a controlled invocation
Invoke manually:
aws lambda invoke \
--function-name my-function \
out.json
If out.json contains valid JSON and the call succeeds, marshalling is fixed.
Pro Tips
- Prefer primitives, dicts, lists — avoid classes in handler returns
- Use explicit serialization in Python to catch hidden DateTime/Decimal issues
- When using API Gateway, always stringify the
bodyfield
Conclusion
“Unable to marshal response” means your Lambda returned an object AWS could not serialize. By logging the raw return value, enforcing JSON-safe structures, removing non-serializable types, and ensuring a correct API Gateway response shape, you restore stable, predictable Lambda behavior.
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
.jpeg)

Comments
Post a Comment