diff --git a/src/SharpCompress/Common/Constants.cs b/src/SharpCompress/Common/Constants.cs
index 9812501d..edd81e08 100644
--- a/src/SharpCompress/Common/Constants.cs
+++ b/src/SharpCompress/Common/Constants.cs
@@ -22,9 +22,11 @@ public static class Constants
/// by rewinding and re-reading the same data.
///
///
- /// Default: 163840 bytes (160KB) - sized to cover ZStandard's worst-case
- /// first block on a tar archive (~131KB including frame header overhead).
- /// ZStandard blocks can be up to 128KB, exceeding the previous 81KB default.
+ /// Default: 81920 bytes (80KB) — sufficient for most formats.
+ /// Formats that require larger buffers (e.g. BZip2, ZStandard) declare their
+ /// own minimum via TarWrapper.MinimumRewindBufferSize, and
+ /// TarWrapper.MaximumRewindBufferSize is used at stream construction
+ /// to ensure the correct capacity is allocated upfront.
///
///
/// Typical usage: 500-1000 bytes for most archives
@@ -41,7 +43,7 @@ public static class Constants
///
///
///
- public static int RewindableBufferSize { get; set; } = 163840;
+ public static int RewindableBufferSize { get; set; } = 81920;
public static CultureInfo DefaultCultureInfo { get; set; } = CultureInfo.InvariantCulture;
}
diff --git a/src/SharpCompress/Compressors/ZStandard/ZstandardConstants.cs b/src/SharpCompress/Compressors/ZStandard/ZstandardConstants.cs
index ac4756d4..a43b2ef1 100644
--- a/src/SharpCompress/Compressors/ZStandard/ZstandardConstants.cs
+++ b/src/SharpCompress/Compressors/ZStandard/ZstandardConstants.cs
@@ -6,4 +6,17 @@ internal class ZstandardConstants
/// Magic number found at start of ZStandard frame: 0xFD 0x2F 0xB5 0x28
///
public const uint MAGIC = 0xFD2FB528;
+
+ ///
+ /// Maximum uncompressed size of a single ZStandard block: ZSTD_BLOCKSIZE_MAX = 128 KB.
+ ///
+ public const int BlockSizeMax = 1 << 17; // 131072 bytes
+
+ ///
+ /// Recommended input (compressed) buffer size for streaming decompression:
+ /// ZSTD_DStreamInSize = ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize (3 bytes).
+ /// The ring buffer must be at least this large to hold the compressed bytes read
+ /// during format detection before the first rewind.
+ ///
+ public const int DStreamInSize = BlockSizeMax + 3;
}
diff --git a/src/SharpCompress/Factories/TarWrapper.cs b/src/SharpCompress/Factories/TarWrapper.cs
index 013debaf..465cf836 100644
--- a/src/SharpCompress/Factories/TarWrapper.cs
+++ b/src/SharpCompress/Factories/TarWrapper.cs
@@ -88,7 +88,11 @@ public class TarWrapper(
ZStandardStream.IsZStandardAsync,
(stream) => new ZStandardStream(stream),
(stream, _) => new ValueTask(new ZStandardStream(stream)),
- ["tar.zst", "tar.zstd", "tzst", "tzstd"]
+ ["tar.zst", "tar.zstd", "tzst", "tzstd"],
+ // ZStandard decompresses in blocks; the compressed size of the first block
+ // can be up to ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize = 131075 bytes.
+ // The ring buffer must hold all compressed bytes read during format detection.
+ minimumRewindBufferSize: ZstandardConstants.DStreamInSize
),
new(
CompressionType.LZip,