{"record":{"id":"6b09211d2ee54785","repo":"prestodb/presto","slug":"generic-internal-error-6b0921","errorCode":"GENERIC_INTERNAL_ERROR","errorMessage":"Encrypted data size is too small: %s. It must be at least the size of the initialization vector: %s.","messagePattern":"Encrypted data size is too small: (.+?)\\. It must be at least the size of the initialization vector: (.+?)\\.","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"critical","filePath":"presto-main-base/src/main/java/com/facebook/presto/spiller/AesSpillCipher.java","lineNumber":54,"sourceCode":"    //  256-bit AES CTR mode\n    private static final String CIPHER_NAME = \"AES/CTR/NoPadding\";\n    private static final int KEY_BITS = 256;\n\n    private SecretKey key;\n    private final int ivBytes;\n\n    AesSpillCipher()\n    {\n        this.key = generateNewSecretKey();\n        this.ivBytes = createEncryptCipher().getIV().length;\n    }\n\n    @Override\n    public ByteBuffer decrypt(ByteBuffer encryptedData)\n    {\n        int length = encryptedData.remaining();\n        if (length < ivBytes) {\n            throw new PrestoException(GENERIC_INTERNAL_ERROR, format(\"Encrypted data size is too small: %s. It must be at least the size of the initialization vector: %s.\", length, ivBytes));\n        }\n        byte[] iv = new byte[ivBytes];\n        encryptedData.get(iv);\n        Cipher cipher = createDecryptCipher(new IvParameterSpec(iv));\n        ByteBuffer output = ByteBuffer.allocate(cipher.getOutputSize(encryptedData.remaining()));\n        try {\n            cipher.doFinal(encryptedData, output);\n            ((Buffer) output).flip();\n            return output;\n        }\n        catch (GeneralSecurityException e) {\n            throw new PrestoException(GENERIC_INTERNAL_ERROR, \"Cannot decrypt previously encrypted data: \" + e.getMessage(), e);\n        }\n    }\n\n    @Override\n    public byte[] decrypt(byte[] encryptedData)\n    {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/spiller/AesSpillCipher.java#L36-L72","documentation":"AesSpillCipher.decrypt requires the encrypted buffer to start with an initialization vector of ivBytes length; if the remaining bytes are fewer than ivBytes the input is not a valid ciphertext produced by this cipher. It is surfaced as GENERIC_INTERNAL_ERROR because corrupt spill data is an internal invariant violation, not a user error.","triggerScenarios":"Calling decrypt(ByteBuffer) with a buffer containing fewer than ivBytes bytes — e.g. a truncated, empty, or plaintext (never-encrypted) spill file being read as encrypted data, or an offset/read bug that misaligns the buffer.","commonSituations":"Spill files truncated by disk-full or premature cleanup; mismatched spill encryption configuration (data written unencrypted but read with an AesSpillCipher, or vice versa); partially written files after a crash; memory/disk corruption.","solutions":["Verify spill encryption configuration matches between write and read paths (spiller cipher settings unchanged across restarts/versions)","Delete/recover the corrupted spill files and re-run the query","Check for disk-full or crash conditions that could truncate spill writes","Investigate reader code for offsets/alignment bugs that shrink the buffer below ivBytes"],"exampleFix":"// before\nByteBuffer decrypted = cipher.decrypt(possiblyTruncatedBuffer);\n// after\nif (encrypted.remaining() >= IV_LENGTH) {\n    ByteBuffer decrypted = cipher.decrypt(encrypted);\n} else {\n    throw new IOException(\"Spill block truncated: \" + encrypted.remaining() + \" bytes\");\n}","handlingStrategy":"validation","validationCode":"if (encryptedData == null || encryptedData.remaining() < IV_LENGTH_BYTES) {\n    throw new IOException(\"Spill block too small to contain IV: \"\n        + (encryptedData == null ? 0 : encryptedData.remaining()) + \" bytes\");\n}","typeGuard":"boolean isPlausibleCiphertext(ByteBuffer buffer) {\n    return buffer != null && buffer.remaining() >= IV_LENGTH_BYTES;\n}","tryCatchPattern":"try {\n    ByteBuffer plain = cipher.decrypt(encrypted);\n} catch (PrestoException e) {\n    if (e.getErrorCode().toCode() == GENERIC_INTERNAL_ERROR.toCode()\n            && e.getMessage().contains(\"too small\")) {\n        // treat spill block as corrupt: discard and recompute/re-read source\n    }\n}","preventionTips":["Never disable spill encryption on some nodes only — keep config uniform across the cluster","Clean stale spill directories after crash or version upgrades","Monitor disk usage to avoid truncated writes","Persist a marker/length header with encrypted blocks so readers can detect truncation"],"tags":["presto","encryption","spill","data-corruption","aes"],"backgroundTag":"corrupt-ciphertext-input","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}