diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js
index 31b8dfca58cbe3..c1403f419c5ea5 100644
--- a/lib/internal/streams/end-of-stream.js
+++ b/lib/internal/streams/end-of-stream.js
@@ -215,7 +215,7 @@ function eos(stream, options, callback) {
     !readable &&
     (!willEmitClose || isReadable(stream)) &&
     (writableFinished || isWritable(stream) === false) &&
-    (wState == null || wState.pendingcb === 0)
+    (wState == null || wState.pendingcb === undefined || wState.pendingcb === 0)
   ) {
     process.nextTick(onclosed);
   } else if (
diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js
index 6820ac18cf4b5c..9d66cbe59b11f3 100644
--- a/test/parallel/test-stream-finished.js
+++ b/test/parallel/test-stream-finished.js
@@ -687,3 +687,16 @@ testClosed((opts) => new Writable({ write() {}, ...opts }));
     assert.strictEqual(stream._writableState.pendingcb, 0);
   }));
 }
+
+{
+  const stream = new Duplex({
+    write(chunk, enc, cb) {}
+  });
+
+  stream.end('foo');
+
+  // Simulate an old stream implementation that doesn't have pendingcb
+  delete stream._writableState.pendingcb;
+
+  finished(stream, { readable: false }, common.mustCall());
+}