Tencent/matrix · error · DataErrorException

DataErrorException

Error message

DataErrorException

What it means

The 7-Zip LZMA C# decoder throws DataErrorException when the compressed stream is corrupt: during the match copy phase the computed distance rep0 exceeds the trained window size plus output produced so far, or exceeds the configured dictionary size check, meaning the decoder was asked to copy from data that was never written — an invalid distance in the LZMA stream.

Solutions

  1. Verify the input bytes are a complete, valid LZMA stream (re-compress the source to confirm)
  2. Ensure SetDecoderProperties is called with the exact 5 property bytes used at compression time (wrong dictionary size can make valid distances appear out of range)
  3. Catch DataErrorException in the caller and treat it as corrupted-input, surfacing a checksum/download retry
  4. Check stream integrity (CRC/length) before decoding to detect truncation early

Example fix

// before
new Lzma.Decoder().Code(inStream, outStream, inSize, outSize, null);

// after
try {
    new Lzma.Decoder().Code(inStream, outStream, inSize, outSize, null);
} catch (Lzma.DataErrorException) {
    throw new IOException("LZMA stream is corrupted or truncated");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before decoding
if (compressedData == null || compressedData.Length == 0)
    throw new IOException("Empty LZMA input");
// verify stored size/CRC matches before decoding

Try / catch

// C#
try {
    decoder.Code(inStream, outStream, inSize, outSize, null);
} catch (DataErrorException ex) {
    // treat as corrupted/truncated input: log, verify source, retry download
    throw new InvalidDataException("LZMA stream corrupt", ex);
}

Prevention

When it happens

Trigger: Decoding a truncated, corrupted, or not-really-LZMA byte stream whose match distance bits decode to a value larger than the dictionary/output window; called via Decoder.Code from Main2 or LzmaBenchmark.

Common situations: Feeding the decoder a file that was compressed with different properties, passing a partially downloaded/corrupted blob, or passing uncompressed data to the LZMA decoder.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/94a309803b12dc36. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-backtrace/src/main/cpp/external/libunwindstack/deps/liblzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs:337

								rep0 = ((2 | (posSlot & 1)) << numDirectBits);
								if (posSlot < Base.kEndPosModelIndex)
									rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
											rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
								else
								{
									rep0 += (m_RangeDecoder.DecodeDirectBits(
										numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
									rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
								}
							}
							else
								rep0 = posSlot;
						}
						if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
						{
							if (rep0 == 0xFFFFFFFF)
								break;
							throw new DataErrorException();
						}
						m_OutWindow.CopyBlock(rep0, len);
						nowPos64 += len;
					}
				}
			}
			m_OutWindow.Flush();
			m_OutWindow.ReleaseStream();
			m_RangeDecoder.ReleaseStream();
		}

		public void SetDecoderProperties(byte[] properties)
		{
			if (properties.Length < 5)
				throw new InvalidParamException();
			int lc = properties[0] % 9;
			int remainder = properties[0] / 9;
			int lp = remainder % 5;

View on GitHub (pinned to 3b8293bd65)