apache/cassandra · error · IOException
failed to encrypt commit log block
Error message
failed to encrypt commit log block
What it means
EncryptionUtils.encryptAndWrite finishes the JCE encryption of a commit log block with cipher.doFinal. If the cipher throws (output buffer too small, block size problems, bad padding state), it is wrapped in IOException("failed to encrypt commit log block").
Solutions
- Check the wrapped JCE exception: ShortBufferException means enlarge outputBuffer (header + input length padding per cipher).
- Verify the cipher returned by CipherFactory.getEncryptor was initialized with a valid key and IV.
- Confirm the JDK/JCE provider is consistent with the configured transformation; update the transformation if the provider changed.
- If reproducible, report/inspect buffer sizing logic in EncryptionUtils against the configured cipher's block size.
Example fix
// before: output buffer too small ByteBuffer out = ByteBuffer.allocate(input.remaining()); // after: leave room for block padding + IV overhead ByteBuffer out = ByteBuffer.allocate(input.remaining() + cipher.getBlockSize());
Defensive patterns
Strategy: try-catch
Validate before calling
int needed = inputBuffer.remaining() + cipher.getBlockSize();
if (outputBuffer.capacity() < needed) throw new IllegalArgumentException("output buffer too small for encryption: need " + needed); Try / catch
try {
EncryptionUtils.encryptAndWrite(cipher, inputBuffer, false, channel);
} catch (IOException e) {
if (e.getMessage().equals("failed to encrypt commit log block")) {
// inspect e.getCause(): ShortBufferException -> enlarge buffer
}
} Prevention
- Size output buffers with cipher block-size headroom
- Use the CipherFactory-managed ciphers (thread-local cached, correctly initialized)
- Run JDK upgrade tests for the encryption path
When it happens
Trigger: encrypt -> encryptAndWrite with an outputBuffer smaller than the cipher's required output size, or a cipher whose doFinal fails mid-block (e.g. uninitialized cipher, wrong key state).
Common situations: Bug-level buffer sizing mismatches between compressed plaintext length and encrypted output capacity, or a JCE provider behaving differently than expected after a JDK upgrade.
Related errors
- commitlog_disk_access_mode =
- could not read encrypted blocked metadata header
- failed to decrypt commit log block
- Unable to seek to position
- a hints file cannot be configured for both compression and…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/799bf1f8b44a1024.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/security/EncryptionUtils.java:110
final int plainTextLength = inputBuffer.remaining();
final int encryptLength = cipher.getOutputSize(plainTextLength);
ByteBuffer outputBuffer = inputBuffer.duplicate();
outputBuffer = ByteBufferUtil.ensureCapacity(outputBuffer, encryptLength, allowBufferResize);
// it's unfortunate that we need to allocate a small buffer here just for the headers, but if we reuse the input buffer
// for the output, then we would overwrite the first n bytes of the real data with the header data.
ByteBuffer intBuf = ByteBuffer.allocate(ENCRYPTED_BLOCK_HEADER_SIZE);
intBuf.putInt(0, encryptLength);
intBuf.putInt(4, plainTextLength);
channel.write(intBuf);
try
{
cipher.doFinal(inputBuffer, outputBuffer);
}
catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException e)
{
throw new IOException("failed to encrypt commit log block", e);
}
outputBuffer.position(0).limit(encryptLength);
channel.write(outputBuffer);
outputBuffer.position(0).limit(encryptLength);
return outputBuffer;
}
public static ByteBuffer encrypt(ByteBuffer inputBuffer, ByteBuffer outputBuffer, boolean allowBufferResize, Cipher cipher) throws IOException
{
Preconditions.checkNotNull(outputBuffer, "output buffer may not be null");
return encryptAndWrite(inputBuffer, new ChannelAdapter(outputBuffer), allowBufferResize, cipher);
}
/**
* Decrypt the input data, as well as manage sizing of the {@code outputBuffer}; if the buffer is not big enough,
* deallocate current, and allocate a large enough buffer.View on GitHub (pinned to 88fd0f6a0e)