user34190: I'm parsing in blocks from my local blk*.dat files, using this excellent website as a guide.
All goes well until file blk00976.dat, block 000000000000000000daf7a26d903543377d5cdddb962077e58fd11212479eea
In my copy of the file, when the parser reaches byte 27871335, it is about to iterate through a set of 64 transaction outputs.
When it reaches the 48th of these, it gets the value c4f1c2b3b69c42c5 and then reads a VarInt of fe80ffffff. This is the number of bytes to read for the next scriptPubKey.
The integer value of the VarInt is 2164260863 bytes (larger than the blk.dat file of 133768162 bytes).
Note the transaction begins with ffffffff58. Implying a version of ffffffff.
A hexdump of the block in question can be found here: https://blockchain.info/rawblock/000000000000000000daf7a26d903543377d5cdddb962077e58fd11212479eea?format=hex (Find "fe80ffffff" to see where I am looking)
A. Is this transaction and/or the block legitimate?
B. If not, why is it in my blk.dat archive?
C. What does a transaction version of ffffffff imply?
D. Is the scriptPubKey size VarInt fe80ffffff correct?
E. What is the story behind this block?

user34190: A. Is this transaction and/or the block legitimate?
Yes - assuming you accept the segwit soft fork and resulting option for BIP144 format transaction serialisation.
B. If not, why is it in my blk.dat archive?
Not applicable: see above.
C. What does a transaction version of ffffffff imply?
This is noise resulting from attempting to read a segwit tx with pre-segwit parsing schema.
D. Is the scriptPubKey size VarInt fe80ffffff correct?
No, this is also noise resulting from attempting to read a segwit tx with pre-segwit parsing schema.
E. What is the story behind this block?
Per Pieter Wuille's comment:

...the block you link is the first segwit block (segregated witness),
a softfork and associated protocol change that introduced a new block
and transaction serialization format. The details are specified in
BIP144: github.com/bitcoin/bips/blob/master/bip-0144.mediawiki. I
strongly suspect that's the cause of what throws off your parser.

BIP144 link
To adjust my parser to accept segwit transactions I had to add a conditional statement after reading the Input Count byte. If this value is one 0x00 then we are dealing with a segwit transaction, we then read the "flag" byte (which should be one 0x01), and then the actual Input Count byte. Finally, we must also read the script witnesses:
Before reading the Locktime, for each transaction input, read:
 NoStackItems <VarInt>
 For each stack item:
    SizeofStackItem <VarInt>
    StackItem <SizeofStackItem bytes>

See also:
https://bitcoin.stackexchange.com/a/110810/34190
https://bitcoin.stackexchange.com/a/55234/34190

34190: <p>I'm parsing in blocks from my local blk*.dat files, using this <a href="https://learnmeabitcoin.com/technical/blkdat" rel="nofollow noreferrer">excellent website</a> as a guide.</p>
<p>All goes well until file <code>blk00976.dat</code>, block <code>000000000000000000daf7a26d903543377d5cdddb962077e58fd11212479eea</code></p>
<p>In my copy of the file, when the parser reaches byte <code>27871335</code>, it is about to iterate through a set of 64 transaction outputs.</p>
<p>When it reaches the 48th of these, it gets the value <code>c4f1c2b3b69c42c5</code> and then reads a VarInt of <code>fe80ffffff</code>. This is the <a href="https://learnmeabitcoin.com/technical/transaction-data" rel="nofollow noreferrer">number of bytes to read for the next <code>scriptPubKey</code></a>.</p>
<p>The integer value of the VarInt is <code>2164260863</code> bytes (larger than the <code>blk.dat</code> file of <code>133768162</code> bytes).</p>
<p>Note the transaction begins with <code>ffffffff58</code>. Implying a version of <code>ffffffff</code>.</p>
<p>A hexdump of the block in question can be found here: <a href="https://blockchain.info/rawblock/000000000000000000daf7a26d903543377d5cdddb962077e58fd11212479eea?format=hex" rel="nofollow noreferrer">https://blockchain.info/rawblock/000000000000000000daf7a26d903543377d5cdddb962077e58fd11212479eea?format=hex</a> (Find &quot;fe80ffffff&quot; to see where I am looking)</p>
<p><strong>A. Is this transaction and/or the block legitimate?</strong></p>
<p><strong>B. If not, why is it in my blk.dat archive?</strong></p>
<p><strong>C. What does a transaction version of <code>ffffffff</code> imply?</strong></p>
<p><strong>D. Is the scriptPubKey size VarInt <code>fe80ffffff</code> correct?</strong></p>
<p><strong>E. What is the story behind this block?</strong></p>
 34190: <p><strong>A. Is this transaction and/or the block legitimate?</strong></p>
<p>Yes - assuming you accept the segwit soft fork and resulting option for BIP144 format transaction serialisation.</p>
<p><strong>B. If not, why is it in my blk.dat archive?</strong></p>
<p>Not applicable: see above.</p>
<p><strong>C. What does a transaction version of <code>ffffffff</code> imply?</strong></p>
<p>This is noise resulting from attempting to read a segwit tx with pre-segwit parsing schema.</p>
<p><strong>D. Is the scriptPubKey size VarInt <code>fe80ffffff</code> correct?</strong></p>
<p>No, this is also noise resulting from attempting to read a segwit tx with pre-segwit parsing schema.</p>
<p><strong>E. What is the story behind this block?</strong></p>
<p>Per Pieter Wuille's comment:</p>
<blockquote>
<p>...the block you link is the first segwit block (segregated witness),
a softfork and associated protocol change that introduced a new block
and transaction serialization format. The details are specified in
BIP144: github.com/bitcoin/bips/blob/master/bip-0144.mediawiki. I
strongly suspect that's the cause of what throws off your parser.</p>
</blockquote>
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki" rel="nofollow noreferrer">BIP144 link</a></p>
<p>To adjust my parser to accept segwit transactions I had to add a conditional statement after reading the Input Count byte. If this value is one <code>0x00</code> then we are dealing with a segwit transaction, we then read the &quot;flag&quot; byte (which should be one <code>0x01</code>), and then the actual Input Count byte. Finally, we must also read the script witnesses:</p>
<p>Before reading the <code>Locktime</code>, for each transaction input, read:</p>
<pre><code> NoStackItems &lt;VarInt&gt;
 For each stack item:
    SizeofStackItem &lt;VarInt&gt;
    StackItem &lt;SizeofStackItem bytes&gt;
</code></pre>
<p>See also:</p>
<p><a href="https://bitcoin.stackexchange.com/a/110810/34190">https://bitcoin.stackexchange.com/a/110810/34190</a>
<a href="https://bitcoin.stackexchange.com/a/55234/34190">https://bitcoin.stackexchange.com/a/55234/34190</a></p>
