FiloSottile/age · error
encrypted size too small: %d
Error message
encrypted size too small: %d
What it means
streamOverhead requires at least the 16-byte stream nonce at the end of the encrypted payload before subtracting it and applying stream.PlaintextSize. A payload smaller than 16 bytes cannot have been produced by age's STREAM encryption, so the size is rejected.
Source
Thrown at internal/inspect/inspect.go:122
done bool
}
func (tr *trackReader) Read(p []byte) (int, error) {
if tr.done {
return 0, io.EOF
}
n, err := tr.r.Read(p)
tr.count += int64(n)
if err == io.EOF {
tr.done = true
}
return n, err
}
func streamOverhead(payloadSize int64) (int64, error) {
const streamNonceSize = 16
if payloadSize < streamNonceSize {
return 0, fmt.Errorf("encrypted size too small: %d", payloadSize)
}
encryptedSize := payloadSize - streamNonceSize
plaintextSize, err := stream.PlaintextSize(encryptedSize)
if err != nil {
return 0, err
}
return payloadSize - plaintextSize, nil
}
View on GitHub (pinned to b74dce4cdb)
Solutions
- Check the input file: a valid age file's payload is at least 16 bytes; empty plaintext still yields a nonce plus framed data
- Re-encrypt or re-download the file if truncated
- Pass the correct fileSize (or -1) to Inspect instead of a miscomputed value
- Treat sub-16-byte payloads as corrupt input and reject them at the caller
Example fix
// before
n, _ := f.Seek(0, io.SeekEnd) // n from a compressed outer file
// after
f.Seek(0, io.SeekStart)
st, _ := f.Stat()
if st.Size() < 200 { return fmt.Errorf("too small to be an age file: %d", st.Size()) }
inspect.Inspect(f, st.Size()) Defensive patterns
Strategy: validation
Validate before calling
st, _ := f.Stat()
if st.Size() < 200 { // header + 16-byte nonce minimum
return fmt.Errorf("not a valid age file: %d bytes", st.Size())
} Type guard
n/a — plain error value; detect via strings.Contains(err.Error(), "encrypted size too small")
Try / catch
data, err := inspect.Inspect(f, size)
if err != nil {
if strings.Contains(err.Error(), "encrypted size too small") {
return fmt.Errorf("corrupt or truncated age file")
}
return err
} Prevention
- Enforce a minimum plausible age file size before inspecting or decrypting
- Never pass computed/outer sizes to Inspect; use the actual file size or -1
- Treat empty-payload encryptions as invalid input at the caller
When it happens
Trigger: inspect.Inspect passes fileSize - data.Sizes.Header < 16 to streamOverhead — the file is nearly empty after the header, or the reported size is wrong.
Common situations: Empty or 0-byte payload files; truncated encrypted files; callers passing an incorrect fileSize (e.g., header-only size, or compressed size of an outer archive); fuzz/corpus inputs.
Related errors
- failed to compute stream overhead: %w
- SSH public key is not an RSA key
- no recipient stanzas
- invalid HRP: %q
- invalid HRP character: hrp[%d]=%d
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/aef62fcbf70bbba2.
Report an issue: GitHub.