diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -69,6 +69,7 @@
 #include "catalog/pg_am.h"
 #include "catalog/pg_amop.h"
 #include "catalog/pg_type.h"
+#include "nodes/miscnodes.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/date.h"
@@ -77,6 +78,7 @@
 #include "utils/inet.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
+#include "utils/numeric.h"
 #include "utils/pg_lsn.h"
 #include "utils/rel.h"
 #include "utils/syscache.h"
@@ -2018,19 +2020,38 @@ brin_minmax_multi_distance_tid(PG_FUNCTION_ARGS)
 Datum
 brin_minmax_multi_distance_numeric(PG_FUNCTION_ARGS)
 {
-	Datum		d;
-	Datum		a1 = PG_GETARG_DATUM(0);
-	Datum		a2 = PG_GETARG_DATUM(1);
+	Numeric		a1 = PG_GETARG_NUMERIC(0);
+	Numeric		a2 = PG_GETARG_NUMERIC(1);
+	Numeric		d;
+	float8		distance;
+	ErrorSaveContext escontext = {T_ErrorSaveContext};
 
 	/*
 	 * We know the values are range boundaries, but the range may be collapsed
 	 * (i.e. single points), with equal values.
 	 */
-	Assert(DatumGetBool(DirectFunctionCall2(numeric_le, a1, a2)));
+	Assert(DatumGetBool(DirectFunctionCall2(numeric_le,
+										  NumericGetDatum(a1), NumericGetDatum(a2))));
+
+	/*
+	 * Distances only guide range merging, so approximations are sufficient.
+	 * Even with finite endpoints, their difference can overflow numeric.  As
+	 * the endpoints are ordered, such a difference is positive.
+	 */
+	d = numeric_sub_safe(a2, a1, (Node *) &escontext);
+	if (SOFT_ERROR_OCCURRED(&escontext))
+		distance = get_float8_infinity();
+	else
+	{
+		distance = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
+													NumericGetDatum(d)));
+		pfree(d);
+	}
 
-	d = DirectFunctionCall2(numeric_sub, a2, a1);	/* a2 - a1 */
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
 
-	PG_RETURN_DATUM(DirectFunctionCall1(numeric_float8, d));
+	PG_RETURN_FLOAT8(distance);
 }
 
 /*
