FiloSottile/age · error
failed to compute stream overhead: %w
Error message
failed to compute stream overhead: %w
What it means
Inspect computes the streaming overhead (nonce + chunk frames) from the encrypted payload size via streamOverhead, which calls stream.PlaintextSize. If the payload is smaller than the 16-byte stream nonce or the size is inconsistent with STREAM framing, this error is returned wrapped.
Source
Thrown at internal/inspect/inspect.go:94
// (which can have LF or CRLF line endings, varying its size), read to
// the end to determine it.
if fileSize == -1 || data.Armor {
n, err := io.Copy(io.Discard, rest)
if err != nil {
return nil, fmt.Errorf("failed to read rest of file: %w", err)
}
fileSize = data.Sizes.Header + n
if !tr.done {
panic("trackReader not done after io.Copy")
}
if tr.count != fileSize && !data.Armor {
panic("trackReader count mismatch")
}
data.Sizes.Armor = tr.count - fileSize
}
data.Sizes.Overhead, err = streamOverhead(fileSize - data.Sizes.Header)
if err != nil {
return nil, fmt.Errorf("failed to compute stream overhead: %w", err)
}
data.Sizes.MinPayload = fileSize - data.Sizes.Header - data.Sizes.Overhead
data.Sizes.MaxPayload = data.Sizes.MinPayload
return data, nil
}
type trackReader struct {
r io.Reader
count int64
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)View on GitHub (pinned to b74dce4cdb)
Solutions
- Verify the file is complete and its declared size is correct
- Re-transfer the file; a payload smaller than 16 bytes cannot be a valid age payload
- Double-check the fileSize argument passed to Inspect (use the real file size; -1 to auto-detect)
- Confirm the file was produced by age and not another tool
Example fix
// before inspect.Inspect(f, size) // size miscounted from armor // after st, _ := f.Stat() inspect.Inspect(f, st.Size()) // let Inspect detect armor and size itself
Defensive patterns
Strategy: validation
Validate before calling
st, _ := f.Stat()
hdrOverhead := int64(200) // generous minimum header size
if st.Size() < hdrOverhead+16 { return fmt.Errorf("file too small to contain a valid age payload") } Type guard
n/a — stream.PlaintextSize returns an error rather than a type mismatch; check it with errors.Is
Try / catch
data, err := inspect.Inspect(f, size)
if err != nil {
if strings.Contains(err.Error(), "stream overhead") { return fmt.Errorf("payload size inconsistent with age STREAM framing") }
return err
} Prevention
- Pass the true file size (or -1) to Inspect — never the size of an outer compressed container
- Reject files smaller than header + 16 bytes before inspection
- Verify completeness of truncated downloads before analysis
When it happens
Trigger: inspect.Inspect calls streamOverhead(fileSize - data.Sizes.Header) and either payloadSize < 16 or stream.PlaintextSize rejects the encrypted size (e.g., size not congruent with chunk + 16-byte tag framing).
Common situations: Inspecting truncated or corrupted age files; files that are shorter than a single chunk plus nonce; non-age data that got past the header by coincidence; arithmetic on wrong fileSize values passed by the caller.
Related errors
- encrypted size too small: %d
- failed to read header: %w
- failed to re-serialize header: %w
- failed to read rest of file: %w
- invalid ciphertext size
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/87dd440f2fba5cf6.
Report an issue: GitHub.