diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out
index c4e749a5a8..f477e239bc 100644
--- a/src/pl/plpython/expected/plpython_types.out
+++ b/src/pl/plpython/expected/plpython_types.out
@@ -700,10 +700,26 @@ CREATE FUNCTION test_type_conversion_mdarray_malformed() RETURNS int[] AS $$
 return [[1,2,3],[4,5]]
 $$ LANGUAGE plpython3u;
 SELECT * FROM test_type_conversion_mdarray_malformed();
-ERROR:  wrong length of inner sequence: has length 2, but 3 was expected
-DETAIL:  To construct a multidimensional array, the inner sequences must all have the same length.
+ERROR:  wrong length of inner list: has length 2, but 3 was expected
+DETAIL:  To construct a multidimensional array, the inner lists must all have the same length.
 CONTEXT:  while creating return value
 PL/Python function "test_type_conversion_mdarray_malformed"
+CREATE FUNCTION test_type_conversion_mdarray_malformed2() RETURNS text[] AS $$
+return [[1,2,3], "abc"]
+$$ LANGUAGE plpython3u;
+SELECT * FROM test_type_conversion_mdarray_malformed2();
+ERROR:  array element is a scalar, but should be a list
+DETAIL:  To construct a multidimensional array, the inner lists must be nested to a uniform depth.
+CONTEXT:  while creating return value
+PL/Python function "test_type_conversion_mdarray_malformed2"
+CREATE FUNCTION test_type_conversion_mdarray_malformed3() RETURNS text[] AS $$
+return ["abc", [1,2,3]]
+$$ LANGUAGE plpython3u;
+SELECT * FROM test_type_conversion_mdarray_malformed3();
+ERROR:  array element is a list, but should be a scalar
+DETAIL:  To construct a multidimensional array, the inner lists must be nested to a uniform depth.
+CONTEXT:  while creating return value
+PL/Python function "test_type_conversion_mdarray_malformed3"
 CREATE FUNCTION test_type_conversion_mdarray_toodeep() RETURNS int[] AS $$
 return [[[[[[[1]]]]]]]
 $$ LANGUAGE plpython3u;
diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c
index 864b5f1765..eddedec3d4 100644
--- a/src/pl/plpython/plpy_typeio.c
+++ b/src/pl/plpython/plpy_typeio.c
@@ -1126,7 +1126,7 @@ PLyObject_ToTransform(PLyObToDatum *arg, PyObject *plrv,
 
 
 /*
- * Convert Python sequence to SQL array.
+ * Convert Python sequence (or list of lists) to SQL array.
  */
 static Datum
 PLySequence_ToArray(PLyObToDatum *arg, PyObject *plrv,
@@ -1205,8 +1205,15 @@ PLySequence_ToArray(PLyObToDatum *arg, PyObject *plrv,
 		dims[0] = PySequence_Length(plrv);
 	}
 
-	/* Allocate space for work arrays, after detecting array size overflow */
 	len = ArrayGetNItems(ndim, dims);
+	if (len == 0)
+	{
+		/* If no elements, ensure we return a zero-D array */
+		array = construct_empty_array(arg->u.array.elmbasetype);
+		return PointerGetDatum(array);
+	}
+
+	/* Allocate space for work arrays, after detecting array size overflow */
 	elems = palloc(sizeof(Datum) * len);
 	nulls = palloc(sizeof(bool) * len);
 
@@ -1246,35 +1253,55 @@ PLySequence_ToArray_recurse(PLyObToDatum *elm, PyObject *list,
 {
 	int			i;
 
-	if (PySequence_Length(list) != dims[dim])
-		ereport(ERROR,
-				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-				 errmsg("wrong length of inner sequence: has length %d, but %d was expected",
-						(int) PySequence_Length(list), dims[dim]),
-				 (errdetail("To construct a multidimensional array, the inner sequences must all have the same length."))));
-
-	if (dim < ndim - 1)
+	/*
+	 * The list nesting depth in all array items must match what
+	 * PLySequence_ToArray saw in the first item.  At the first dimension, we
+	 * might have a non-list sequence, but recurse anyway.
+	 */
+	if (dim == 0 || PyList_Check(list))
 	{
-		for (i = 0; i < dims[dim]; i++)
-		{
-			PyObject   *sublist = PySequence_GetItem(list, i);
+		int			thisdim = PySequence_Length(list);
 
-			PLySequence_ToArray_recurse(elm, sublist, dims, ndim, dim + 1,
-										elems, nulls, currelem);
-			Py_XDECREF(sublist);
-		}
-	}
-	else
-	{
-		for (i = 0; i < dims[dim]; i++)
+		if (thisdim < 0)
+			PLy_elog(ERROR, "could not determine sequence length for function return value");
+
+		/* like PLySequence_ToArray, we treat 0-length list as a scalar */
+		if (thisdim > 0)
 		{
-			PyObject   *obj = PySequence_GetItem(list, i);
+			/* Check for uniform array structure */
+			if (dim >= ndim)
+				ereport(ERROR,
+						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+						 errmsg("array element is a list, but should be a scalar"),
+						 (errdetail("To construct a multidimensional array, the inner lists must be nested to a uniform depth."))));
+			if (thisdim != dims[dim])
+				ereport(ERROR,
+						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+						 errmsg("wrong length of inner list: has length %d, but %d was expected",
+								thisdim, dims[dim]),
+						 (errdetail("To construct a multidimensional array, the inner lists must all have the same length."))));
+			/* OK, so recurse */
+			for (i = 0; i < thisdim; i++)
+			{
+				PyObject   *sublist = PySequence_GetItem(list, i);
 
-			elems[*currelem] = elm->func(elm, obj, &nulls[*currelem], true);
-			Py_XDECREF(obj);
-			(*currelem)++;
+				PLySequence_ToArray_recurse(elm, sublist, dims, ndim, dim + 1,
+											elems, nulls, currelem);
+				Py_XDECREF(sublist);
+			}
+			return;
 		}
 	}
+
+	/* The "list" is, or should be treated as, a scalar */
+	if (dim != ndim)
+		ereport(ERROR,
+				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+				 errmsg("array element is a scalar, but should be a list"),
+				 (errdetail("To construct a multidimensional array, the inner lists must be nested to a uniform depth."))));
+
+	elems[*currelem] = elm->func(elm, list, &nulls[*currelem], true);
+	(*currelem)++;
 }
 
 
diff --git a/src/pl/plpython/sql/plpython_types.sql b/src/pl/plpython/sql/plpython_types.sql
index 9702a10a72..b57b9a6463 100644
--- a/src/pl/plpython/sql/plpython_types.sql
+++ b/src/pl/plpython/sql/plpython_types.sql
@@ -341,6 +341,18 @@ $$ LANGUAGE plpython3u;
 
 SELECT * FROM test_type_conversion_mdarray_malformed();
 
+CREATE FUNCTION test_type_conversion_mdarray_malformed2() RETURNS text[] AS $$
+return [[1,2,3], "abc"]
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM test_type_conversion_mdarray_malformed2();
+
+CREATE FUNCTION test_type_conversion_mdarray_malformed3() RETURNS text[] AS $$
+return ["abc", [1,2,3]]
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM test_type_conversion_mdarray_malformed3();
+
 CREATE FUNCTION test_type_conversion_mdarray_toodeep() RETURNS int[] AS $$
 return [[[[[[[1]]]]]]]
 $$ LANGUAGE plpython3u;
