diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index fedaed533b..1a22966211 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1258,6 +1258,10 @@ CREATE VIEW pg_stat_progress_copy AS
                       WHEN 3 THEN 'PIPE'
                       WHEN 4 THEN 'CALLBACK'
                       END AS "type",
+        CASE S.param7 WHEN 0 THEN 'IN PROG'
+                      WHEN 1 THEN 'ERR'
+                      WHEN 2 THEN 'PASS'
+                      END AS 'status',
         S.param1 AS bytes_processed,
         S.param2 AS bytes_total,
         S.param3 AS tuples_processed,
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index 35a1d3a774..e0427e6e2f 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -116,6 +116,8 @@ CopyFromErrorCallback(void *arg)
 {
 	CopyFromState cstate = (CopyFromState) arg;
 
+	cstate->status = CP_ERROR;
+	pgstat_progress_update_param(PROGRESS_COPY_STATUS, cstate->status);
 	if (cstate->opts.binary)
 	{
 		/* can't usefully display the data */
diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
index fca29a9a10..e64ff44273 100644
--- a/src/backend/commands/copyto.c
+++ b/src/backend/commands/copyto.c
@@ -97,6 +97,7 @@ typedef struct CopyToStateData
 	FmgrInfo   *out_functions;	/* lookup info for output functions */
 	MemoryContext rowcontext;	/* per-row evaluation context */
 	uint64		bytes_processed;	/* number of bytes processed so far */
+	int			status;			/* See PROGRESS_COPY_STATUS */
 } CopyToStateData;
 
 /* DestReceiver for COPY (query) TO */
@@ -329,6 +330,9 @@ EndCopy(CopyToState cstate)
 	}
 
 	pgstat_progress_end_command();
+	if (!cstate->status)
+		cstate->status = CP_SUCCESS;
+	pgstat_progress_update_param(PROGRESS_COPY_STATUS, cstate->status);
 
 	MemoryContextDelete(cstate->copycontext);
 	pfree(cstate);
@@ -655,6 +659,7 @@ BeginCopyTo(ParseState *pstate,
 	cstate->encoding_embeds_ascii = PG_ENCODING_IS_CLIENT_ONLY(cstate->file_encoding);
 
 	cstate->copy_dest = COPY_FILE;	/* default */
+	cstate->status = CP_IN_PROG;
 
 	if (pipe)
 	{
diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c
index f29199725b..eda27f2393 100644
--- a/src/backend/utils/activity/backend_progress.c
+++ b/src/backend/utils/activity/backend_progress.c
@@ -107,6 +107,7 @@ pgstat_progress_end_command(void)
 
 	PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
 	beentry->st_progress_command = PROGRESS_COMMAND_INVALID;
-	beentry->st_progress_command_target = InvalidOid;
+	// We keep beentry->st_progress_command_target so that user can query copy progress
+	// after the COPY command finishes.
 	PGSTAT_END_WRITE_ACTIVITY(beentry);
 }
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 893690dad5..1cfc86a6dc 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -503,10 +503,9 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 		beentry = &local_beentry->backendStatus;
 
 		/*
-		 * Report values for only those backends which are running the given
-		 * command.
+		 * Report values for only those backends which are running or have run.
 		 */
-		if (!beentry || beentry->st_progress_command != cmdtype)
+		if (!beentry || beentry->st_progress_command_target == InvalidOid)
 			continue;
 
 		/* Value available to all callers */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 3df1c5a97c..63f1281d84 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -164,6 +164,7 @@ typedef struct CopyFromStateData
 #define RAW_BUF_BYTES(cstate) ((cstate)->raw_buf_len - (cstate)->raw_buf_index)
 
 	uint64		bytes_processed;	/* number of bytes processed so far */
+	int			status;		/* See PROGRESS_COPY_STATUS */
 } CopyFromStateData;
 
 extern void ReceiveCopyBegin(CopyFromState cstate);
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index a28938caf4..39ea358e42 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -140,6 +140,14 @@
 #define PROGRESS_COPY_TUPLES_EXCLUDED 3
 #define PROGRESS_COPY_COMMAND 4
 #define PROGRESS_COPY_TYPE 5
+#define PROGRESS_COPY_STATUS 6 // See progress_type below
+
+enum progress_type
+{
+    CP_IN_PROG,
+    CP_ERROR,
+    CP_SUCCESS
+};
 
 /* Commands of COPY (as advertised via PROGRESS_COPY_COMMAND) */
 #define PROGRESS_COPY_COMMAND_FROM 1
