ppy/osu · error
input .lzma is too short
Error message
input .lzma is too short
What it means
Thrown inside readCompressedData when the LZMA replay payload cannot supply the first 5 bytes (the LZMA properties header). The stream is truncated before the decoder can even begin, so the replay is structurally invalid. This is a hard data-integrity failure, not a decode problem.
Source
Thrown at osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs:174
if (decodedRank != null)
score.ScoreInfo.Rank = decodedRank.Value;
// before returning for database import, we must restore the database-sourced BeatmapInfo.
// if not, the clone operation in GetPlayableBeatmap will cause a dereference and subsequent database exception.
score.ScoreInfo.BeatmapInfo = workingBeatmap.BeatmapInfo;
score.ScoreInfo.BeatmapHash = workingBeatmap.BeatmapInfo.Hash;
return score;
}
private void readCompressedData(byte[] data, Action<StreamReader> readFunc)
{
using (var replayInStream = new MemoryStream(data))
{
byte[] properties = new byte[5];
if (replayInStream.Read(properties, 0, 5) != 5)
throw new IOException("input .lzma is too short");
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = replayInStream.ReadByte();
if (v < 0)
throw new IOException("Can't Read 1");
outSize |= (long)(byte)v << (8 * i);
}
long compressedSize = replayInStream.Length - replayInStream.Position;
using (var lzma = LzmaStream.Create(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
readFunc(reader);
}
View on GitHub (pinned to d9c73e12ad)
Solutions
- Verify the source .osr file size is non-trivially larger than 5 bytes and re-download/re-extract if it is truncated.
- Check the upstream writer/encoder to confirm it flushes the full LZMA blob before closing the stream.
- Catch IOException around the decode path and report a 'corrupt replay' user message rather than letting it propagate.
- If importing many replays, quarantine files that fail this check instead of aborting the whole import.
Example fix
// before
if (replayInStream.Read(properties, 0, 5) != 5)
throw new IOException("input .lzma is too short");
// after (caller-side guard)
if (data.Length < 13) // 5 props + 8 size bytes minimum
throw new IOException($"Replay payload too short ({data.Length} bytes); file is corrupt."); Defensive patterns
Strategy: validation
Validate before calling
if (data == null || data.Length < 13)
throw new IOException("Replay payload is truncated; cannot decode."); Try / catch
try { readCompressedData(data, readFunc); }
catch (IOException) { /* mark replay corrupt, skip import */ } Prevention
- Pre-validate replay payload length before LZMA decode.
- Quarantine short/corrupt files during batch import.
- Verify replay file integrity (checksum/size) on download.
When it happens
Trigger: Replay data array passed to readCompressedData is shorter than 5 bytes, or is empty. Happens with partially downloaded/extracted .osr replay files or a truncated embedded replay stream.
Common situations: Corrupt .osr file download (network cut mid-transfer), replay writer produced a zero-length compressed blob, or the wrong byte slice was handed to the decoder.
Related errors
- Can't Read 1
- Bad ticks count read!
- Deserialization of arbitrary type is not supported.
- Legacy replay cannot be converted for the ruleset: {currentR
- Unknown hit object type.
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/e49425025fc60617.
Report an issue: GitHub.