diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile
index 85394b4f1f..681f3bff2b 100644
--- a/contrib/postgres_fdw/Makefile
+++ b/contrib/postgres_fdw/Makefile
@@ -4,6 +4,8 @@ MODULE_big = postgres_fdw
 OBJS = postgres_fdw.o option.o deparse.o connection.o shippable.o $(WIN32RES)
 PGFILEDESC = "postgres_fdw - foreign data wrapper for PostgreSQL"
 
+TAP_TESTS = 1
+
 PG_CPPFLAGS = -I$(libpq_srcdir)
 SHLIB_LINK_INTERNAL = $(libpq)
 
diff --git a/contrib/postgres_fdw/t/001_copy_same_txn_rem.pl b/contrib/postgres_fdw/t/001_copy_same_txn_rem.pl
new file mode 100644
index 0000000000..66f9c76b0d
--- /dev/null
+++ b/contrib/postgres_fdw/t/001_copy_same_txn_rem.pl
@@ -0,0 +1,77 @@
+# Test COPY FROM inside a transaction along a table creation for multiple WAL levels
+#
+# COPY done to foreign tables should not use heap_insert options.
+# Regression test for BUG#15552
+use strict;
+use warnings;
+
+use PostgresNode;
+use TestLib;
+use Test::More tests => 4;
+
+# Wrapper routine tunable for wal_level.
+sub run_copy_same_txn_wal
+{
+	my $wal_level = shift;
+
+	my $node = get_new_node("node_$wal_level");
+	$node->init;
+	$node->append_conf('postgresql.conf', qq(
+wal_level = $wal_level
+));
+	$node->start;
+
+    my ($database,$port);
+
+    $database = $node->safe_psql('postgres', "SELECT current_database();");
+    $port = $node->safe_psql('postgres', "SELECT current_setting('port');");
+
+	$node->safe_psql('postgres', "
+        CREATE EXTENSION postgres_fdw;
+
+        CREATE SERVER testserver FOREIGN DATA WRAPPER postgres_fdw;
+        DO \$d\$
+            BEGIN
+                EXECUTE \$c\$
+                 CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw
+                      OPTIONS (dbname '$database', port '$port')
+                    \$c\$;
+            END;
+        \$d\$;
+        CREATE USER MAPPING FOR public SERVER testserver
+            OPTIONS (user 'value', password 'value');
+        CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
+
+        CREATE TABLE loc (a INT, b TEXT);");
+
+    my $stderr;
+	$node->psql('postgres', "
+		BEGIN;
+        CREATE FOREIGN TABLE test_copy_same_txn_rem (a INT, b TEXT) SERVER
+                loopback OPTIONS(table_name 'loc');
+        COPY test_copy_same_txn_rem FROM STDIN DELIMITER ',';
+1,f
+\\\.
+		COMMIT;",
+        stderr => \$stderr
+     );
+
+    is($stderr, '', "Ensure no error is emitted");
+
+    my $stdout;
+    $node->psql('postgres', "
+        SELECT * FROM test_copy_same_txn_rem;",
+        stdout => \$stdout
+    );
+
+    is($stdout, "1|f", "Verify table content");
+
+	$node->stop('immediate');
+	$node->teardown_node;
+	$node->clean_node;
+	return;
+}
+
+# Run same test suite for multiple wal_level values.
+run_copy_same_txn_wal("replica");
+run_copy_same_txn_wal("minimal");
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 4311e16007..fb7acc361e 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2401,6 +2401,7 @@ CopyFrom(CopyState cstate)
 	 */
 	/* createSubid is creation check, newRelfilenodeSubid is truncation check */
 	if (cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
+	    cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
 		(cstate->rel->rd_createSubid != InvalidSubTransactionId ||
 		 cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId))
 	{
