diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 26d293709a..94589d0cdb 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -312,6 +312,7 @@ makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
 
 	lex->input = lex->token_terminator = lex->line_start = json;
 	lex->line_number = 1;
+	lex->pos_last_linefeed = 0;
 	lex->input_length = len;
 	if (need_escapes)
 		lex->strval = makeStringInfo();
@@ -623,7 +624,10 @@ json_lex(JsonLexContext *lex)
 		   (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
 	{
 		if (*s == '\n')
+		{
 			++lex->line_number;
+			lex->pos_last_linefeed = len;
+		}
 		++s;
 		++len;
 	}
@@ -1264,17 +1268,15 @@ report_json_context(JsonLexContext *lex)
 	const char *context_start;
 	const char *context_end;
 	const char *line_start;
-	int			line_number;
 	char	   *ctxt;
 	int			ctxtlen;
 	const char *prefix;
 	const char *suffix;
 
 	/* Choose boundaries for the part of the input we will display */
-	context_start = lex->input;
+	context_start = lex->input + lex->pos_last_linefeed;
 	context_end = lex->token_terminator;
 	line_start = context_start;
-	line_number = 1;
 	for (;;)
 	{
 		/* Always advance over newlines */
@@ -1282,7 +1284,6 @@ report_json_context(JsonLexContext *lex)
 		{
 			context_start++;
 			line_start = context_start;
-			line_number++;
 			continue;
 		}
 		/* Otherwise, done as soon as we are close enough to context_end */
@@ -1317,7 +1318,7 @@ report_json_context(JsonLexContext *lex)
 	suffix = (lex->token_type != JSON_TOKEN_END && context_end - lex->input < lex->input_length && *context_end != '\n' && *context_end != '\r') ? "..." : "";
 
 	return errcontext("JSON data, line %d: %s%s%s",
-					  line_number, prefix, ctxt, suffix);
+					  lex->line_number, prefix, ctxt, suffix);
 }
 
 /*
diff --git a/src/include/utils/jsonapi.h b/src/include/utils/jsonapi.h
index 5f4d479a7b..3b47fae7e7 100644
--- a/src/include/utils/jsonapi.h
+++ b/src/include/utils/jsonapi.h
@@ -57,6 +57,7 @@ typedef struct JsonLexContext
 	char	   *prev_token_terminator;
 	JsonTokenType token_type;
 	int			lex_level;
+	int			pos_last_linefeed;
 	int			line_number;
 	char	   *line_start;
 	StringInfo	strval;
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index 69b0a6ee6d..b772db7ef8 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -272,6 +272,42 @@ LINE 1: SELECT '    '::json;
                ^
 DETAIL:  The input string ended unexpectedly.
 CONTEXT:  JSON data, line 1:     
+-- Multi-line JSON input to check ERROR reporting
+SELECT jsonb_pretty('{
+		"one": 1,
+		"two":"two",
+		"three":
+			true}'::jsonb); -- OK
+   jsonb_pretty    
+-------------------
+ {                +
+     "one": 1,    +
+     "two": "two",+
+     "three": true+
+ }
+(1 row)
+
+SELECT jsonb_pretty('{
+		"one": 1,
+		"two":,"two", -- ERROR extraneous comma before field "two" value, line 3
+		"three":
+			true}'::jsonb);
+ERROR:  invalid input syntax for type json
+LINE 1: SELECT jsonb_pretty('{
+                            ^
+DETAIL:  Expected JSON value, but found ",".
+CONTEXT:  JSON data, line 3: 		"two":,...
+SELECT jsonb_pretty('{
+		"one": 1,
+		"two":"two",
+		"three":
+			}'::jsonb); -- ERROR missing value for field "three", line 5
+ERROR:  invalid input syntax for type json
+LINE 1: SELECT jsonb_pretty('{
+                            ^
+DETAIL:  Expected JSON value, but found "}".
+CONTEXT:  JSON data, line 5: 			}
+-- ERROR is on line 5 because a LF \n is legal whitespace at end of line 4, so the missing syntax is on line 5
 --constructors
 -- array_to_json
 SELECT array_to_json(array(select 1 as a));
diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql
index e021664592..f7187a7a0b 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -59,6 +59,24 @@ SELECT 'trues'::json;			-- ERROR, not a keyword
 SELECT ''::json;				-- ERROR, no value
 SELECT '    '::json;			-- ERROR, no value
 
+-- Multi-line JSON input to check ERROR reporting
+SELECT jsonb_pretty('{
+		"one": 1,
+		"two":"two",
+		"three":
+			true}'::jsonb); -- OK
+SELECT jsonb_pretty('{
+		"one": 1,
+		"two":,"two", -- ERROR extraneous comma before field "two" value, line 3
+		"three":
+			true}'::jsonb);
+SELECT jsonb_pretty('{
+		"one": 1,
+		"two":"two",
+		"three":
+			}'::jsonb); -- ERROR missing value for field "three", line 5
+-- ERROR is on line 5 because a LF \n is legal whitespace at end of line 4, so the missing syntax is on line 5
+
 --constructors
 -- array_to_json
 
