diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js
index d1603f6a024b81..561216c353c605 100644
--- a/lib/internal/fs/streams.js
+++ b/lib/internal/fs/streams.js
@@ -272,7 +272,8 @@ function closeFsStream(stream, cb, err) {
     er = er || err;
     cb(er);
     stream.closed = true;
-    if (!er)
+    const s = stream._writableState || stream._readableState;
+    if (!er && !s.emitClose)
       stream.emit('close');
   });
 
diff --git a/test/parallel/test-file-write-stream4.js b/test/parallel/test-file-write-stream4.js
new file mode 100644
index 00000000000000..2a81efcb66756f
--- /dev/null
+++ b/test/parallel/test-file-write-stream4.js
@@ -0,0 +1,21 @@
+'use strict';
+
+// Test that 'close' emits once and not twice when `emitClose: true` is set.
+// Refs: https://github.com/nodejs/node/issues/31366
+
+const common = require('../common');
+const path = require('path');
+const fs = require('fs');
+
+const tmpdir = require('../common/tmpdir');
+tmpdir.refresh();
+
+const filepath = path.join(tmpdir.path, 'write_pos.txt');
+
+const fileReadStream = fs.createReadStream(process.execPath);
+const fileWriteStream = fs.createWriteStream(filepath, {
+  emitClose: true
+});
+
+fileReadStream.pipe(fileWriteStream);
+fileWriteStream.on('close', common.mustCall());