pulumi/pulumi · error
encryptedlog: invalid session key size %d
Error message
encryptedlog: invalid session key size %d
What it means
The session key decrypted from the header does not have the expected keySize length (32 bytes for AES-256). Decryption succeeded, but the plaintext key is the wrong size, so the reader rejects it instead of constructing a cipher with an invalid key.
Source
Thrown at pkg/engine/encryptedlog/reader.go:77
var keyLenBuf [2]byte
if _, err := io.ReadFull(r, keyLenBuf[:]); err != nil {
return nil, fmt.Errorf("encryptedlog: reading key length: %w", err)
}
keyLen := binary.BigEndian.Uint16(keyLenBuf[:])
encryptedKeyBytes := make([]byte, keyLen)
if _, err := io.ReadFull(r, encryptedKeyBytes); err != nil {
return nil, fmt.Errorf("encryptedlog: reading encrypted key: %w", err)
}
decryptedKey, err := dec.DecryptValue(ctx, string(encryptedKeyBytes))
if err != nil {
return nil, fmt.Errorf("encryptedlog: decrypting session key: %w", err)
}
sessionKey := []byte(decryptedKey)
if len(sessionKey) != keySize {
return nil, fmt.Errorf("encryptedlog: invalid session key size %d", len(sessionKey))
}
// Set up AES-256-GCM from the session key.
block, err := aes.NewCipher(sessionKey)
if err != nil {
return nil, fmt.Errorf("encryptedlog: creating cipher: %w", err)
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("encryptedlog: creating GCM: %w", err)
}
return &Reader{cd: &chunkDecrypter{r: r, aesgcm: aesgcm}}, nil
}
// Read reads decrypted, decompressed log data.
func (elr *Reader) Read(p []byte) (int, error) {
return elr.cd.Read(p)View on GitHub (pinned to 793f7b2e16)
Solutions
- Confirm the encrypted log and the decrypter belong to the same stack/deployment (same secret key material).
- Check whether your secrets provider returns decoded raw bytes; unwrap/base64-decode if it returns an envelope.
- Re-export the log so it is written with the current secrets provider and key.
Example fix
// before: decrypting ciphertext from a different stack dec := stackDecrypter(otherStack) rdr, err := encryptedlog.NewReader(ctx, f, dec) // invalid session key size // after: use the decrypter for the stack that produced the log dec := stackDecrypter(logSourceStack) rdr, err := encryptedlog.NewReader(ctx, f, dec)
Defensive patterns
Strategy: validation
Validate before calling
plain, err := dec.DecryptValue(ctx, ciphertextB64)
if err == nil && len(plain) != 32 {
return fmt.Errorf("decrypter returned %d bytes, expected a 32-byte AES-256 key; wrong stack/provider?", len(plain))
} Try / catch
rdr, err := encryptedlog.NewReader(ctx, r, dec)
if err != nil && strings.Contains(err.Error(), "invalid session key size") {
return errors.New("decrypter does not correspond to this log's secrets provider; use the originating stack's decrypter")
} Prevention
- Pair each log with the decrypter of the stack that wrote it.
- Test-decrypt a known ciphertext after changing secrets providers.
- Avoid decrypters that return wrapped/encoded values; unwrap to raw bytes first.
When it happens
Trigger: Calling NewReader with a Decrypter that returns something other than the raw 32-byte session key — e.g. decrypting ciphertext that was not the session key (wrong stack's ciphertext), or a decrypter that returns a wrapper/JSON envelope rather than raw bytes.
Common situations: Pointing a decrypter at a ciphertext from a different stack or file; secrets providers that base64-wrap values; mixing log files and secret configurations from different deployments.
Related errors
- encryptedlog: creating cipher: %w
- encryptedlog: creating GCM: %w
- encryptedlog: reading version: %w
- encryptedlog: unsupported version %d
- encryptedlog: reading key length: %w
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/1e5e8adca71118d9.
Report an issue: GitHub.