juicedata/juicefs · error

encrypt_chunked: ciphertext %d exceeds capacity %d

Error message

encrypt_chunked: ciphertext %d exceeds capacity %d

What it means

When encrypting a chunk, the writer assumes the ciphertext fits in n+overhead bytes (AEAD tag plus a small margin). If the encryptor returns more bytes than that reserved capacity — an internal invariant violation — the write aborts rather than produce a chunk that cannot be parsed back.

Source

Thrown at pkg/object/encrypt_chunked.go:240

	plain := cr.pool.Get().(*[]byte)
	defer cr.pool.Put(plain)

	n, readErr := io.ReadFull(cr.r, *plain)
	if n == 0 {
		if readErr == io.EOF || readErr == io.ErrUnexpectedEOF {
			cr.done = true
			return 0, io.EOF
		}
		return 0, readErr
	}

	ct, err := cr.enc.Encrypt((*plain)[:n])
	if err != nil {
		return 0, err
	}
	fixedCtLen := n + cr.overhead
	if len(ct) > fixedCtLen {
		return 0, fmt.Errorf("encrypt_chunked: ciphertext %d exceeds capacity %d", len(ct), fixedCtLen)
	}

	chunk := make([]byte, chunkHeaderSize+fixedCtLen)
	binary.BigEndian.PutUint32(chunk[:chunkHeaderSize], uint32(len(ct)))
	copy(chunk[chunkHeaderSize:], ct)

	copied := copy(p, chunk)
	if copied < len(chunk) {
		cr.buf = chunk[copied:]
	}

	if readErr == io.EOF || readErr == io.ErrUnexpectedEOF {
		cr.done = true
	} else if readErr != nil {
		return copied, readErr
	}
	return copied, nil
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Do not add/modify ciphers without updating the overhead calculation in the chunked encryptor construction
  2. Report/inspect as a bug: check the JuiceFS version and include the encrypt-algo in the report
  3. Use a stock supported algorithm (aes256gcm-rsa, chacha20-rsa, sm4gcm) which satisfies the overhead invariant
  4. Retry on a stock build if you are running a patched/forked client

Example fix

// before (custom build)
return &dataEncryptor{keyEncryptor, 32, aead} // overhead mismatch in chunked mode
// after
return &chunkedEncryptedObject{...} with overhead matching the AEAD tag size (16)
Defensive patterns

Strategy: try-catch

Try / catch

n, err := r.Read(buf)
if err != nil && strings.Contains(err.Error(), "exceeds capacity") {
	// internal invariant: report bug with version + encrypt-algo; use stock build
}

Prevention

When it happens

Trigger: Calling Read on a chunkedEncryptedReader whose enc.Encrypt returns ciphertext longer than plaintext+overhead, e.g. an encryptor with a larger overhead than declared at construction (chunked mode uses a fixed 16-byte overhead assumption for its algorithms).

Common situations: Adding a new cipher to NewDataEncryptor without updating the chunked overhead assumption; library-level bug rather than user misconfiguration; data path patched or forked.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/92afda720545ff4b. Report an issue: GitHub.