prestodb/presto · error · MalformedInputException
Zstd JNI decompressor failed with
Error message
Zstd JNI decompressor failed with
What it means
ZstdJniDecompressor delegates to the Zstd JNI library; if Zstd reports an error code for the input bytes, a MalformedInputException is thrown embedding the JNI error name. The compressed block data did not decode as valid Zstandard.
Source
Thrown at presto-orc/src/main/java/com/facebook/presto/orc/zstd/ZstdJniDecompressor.java:35
import io.airlift.compress.Decompressor;
import io.airlift.compress.MalformedInputException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import static java.lang.StrictMath.toIntExact;
public class ZstdJniDecompressor
implements Decompressor
{
@Override
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
long size = Zstd.decompressByteArray(output, 0, maxOutputLength, input, inputOffset, inputLength);
if (Zstd.isError(size)) {
String errorName = Zstd.getErrorName(size);
throw new MalformedInputException(inputOffset, "Zstd JNI decompressor failed with " + errorName);
}
return toIntExact(size);
}
@Override
public void decompress(ByteBuffer input, ByteBuffer output)
throws MalformedInputException
{
if (input.isDirect() || output.isDirect() || !input.hasArray() || !output.hasArray()) {
throw new IllegalArgumentException("Non-direct byte buffer backed by byte array required");
}
int inputOffset = input.arrayOffset() + input.position();
int outputOffset = output.arrayOffset() + output.position();
int written = decompress(input.array(), inputOffset, input.remaining(), output.array(), outputOffset, output.remaining());
((Buffer) output).position(output.position() + written);
}
}View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the ORC file's compression kind metadata matches ZSTD.
- Scan the file with orc-tools to find the corrupt block.
- Update the zstd-jni native library to a compatible version.
- Re-transfer/repair the corrupted file.
Example fix
// before
compressor = new ZstdJniDecompressor();
// after: confirm codec from file metadata first
if (metadata.getCompressionKind() != CompressionKind.ZSTD) {
compressor = Decompressor.forKind(metadata.getCompressionKind());
} else {
compressor = new ZstdJniDecompressor();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (metadata.getCompressionKind() != CompressionKind.ZSTD) {
throw new IOException("codec mismatch, not zstd: " + metadata.getCompressionKind());
} Try / catch
try { return zstdDecompressor.decompress(in, off, len, out, oOff, max); } catch (MalformedInputException e) {
throw new DataCorruptionException("zstd decode failed: " + e.getMessage(), e);
} Prevention
- Verify compression kind in footer matches reader's decompressor.
- Keep zstd-jni version compatible with the writer's zstd version.
- Detect truncated frames via block-length sanity checks.
- Run integrity scans on ingested files.
When it happens
Trigger: decompress called on bytes that are not valid Zstd (corruption, wrong block offset, or codec mismatch — e.g., file compressed with snappy but read as zstd).
Common situations: ORC file compression kind misread/mismatched; corrupted block boundaries; truncated zstd frame; incompatible zstd-jni version vs. writer's dictionary/frame features.
Related errors
- NOT_SUPPORTED
- Unsupported compression for verification:
- Write-side compression verification failed: %s (uncompressed
- Write-side compression verification failed: chunk does not d
- compression not implemented yet
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/ae6a1a351f721438.
Report an issue: GitHub.