I am trying to create and run a lambda function from within Redshift.
I have scaled the lambda_handler
back to something very simple
def lambda_handler(event, context):
print("Received event:", event)
value = 42
print("Returning value:", value, "type:", type(value))
result = [[value]]
print("JSON result to return:", result)
return result
I have also tried setting result
as 42
and [42]
.
My create external function statement is
CREATE OR REPLACE EXTERNAL FUNCTION test_fn()
RETURNS INT
VOLATILE
LAMBDA 'arn:aws:.........'
IAM_ROLE 'arn:aws:iam::........';
However I keep getting the error:
SQL Error [XX000]: ERROR: Invalid External Function Response
Detail:
-----------------------------------------------
error: Invalid External Function Response
code: 8001
context: Cannot parse External Function response
query: 0
location: exfunc_data.cpp:374
process: padbmaster [pid=1073939252]
-----------------------------------------------
I am using a cluster of 2 ra3.large nodes which is patched to version 191.
I am expecting Redshift to return the value 42 when calling SELECT test_fn();
Why Redshift can’t parse your Lambda response — and the minimal fix
Redshift Lambda UDFs must return a JSON string whose top level has a field named results
. results
must be an array with one element per input row Redshift sends in event["arguments"]
. If you return a bare value, a Python list, or anything that isn’t a JSON string with {"results": [...]}
, Redshift throws “Cannot parse External Function response”.
Minimal working Python handler (for a no‑arg UDF)
import json
def lambda_handler(event, context):
# Redshift batches rows in event["arguments"]
rows = event["arguments"] # e.g., [ [] ] for SELECT my_fn();
results = [42] * len(rows) # one output per input row
return json.dumps({"results": results})
Checklist
The handler returns json.dumps({...})
, not a raw Python object.
Top‑level key is exactly results
.
len(return_payload["results"]) == len(event["arguments"])
.
Your SQL UDF’s return type matches the Python values you put in results
.
If you add parameters later, each “row” in event["arguments"]
will be an array of those values; compute one scalar per row and place them in results
.