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

  1. Check the input file: a valid age file's payload is at least 16 bytes; empty plaintext still yields a nonce plus framed data
  2. Re-encrypt or re-download the file if truncated
  3. Pass the correct fileSize (or -1) to Inspect instead of a miscomputed value
  4. 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

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


AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31). Data as JSON: /api/errors/aef62fcbf70bbba2. Report an issue: GitHub.