juicedata/juicefs · error

Decrypt: truncated chunk header

Error message

Decrypt: truncated chunk header

What it means

The chunked encrypted reader reads fixed-size chunks, each starting with a 4-byte big-endian header holding the ciphertext length. If a read yields fewer bytes than that header (chunkHeaderSize), the stream is incomplete and 'Decrypt: truncated chunk header' is raised.

Source

Thrown at pkg/object/encrypt_chunked.go:160

			r.putChunkBuf()
		}
		return n, nil
	}
	chunkBuf := r.pool.Get().(*[]byte)
	defer func() {
		if len(r.buf) == 0 {
			r.pool.Put(chunkBuf)
		}
	}()

	n, err := io.ReadFull(r.r, *chunkBuf)
	chunk := (*chunkBuf)[:n]
	if err != io.ErrUnexpectedEOF && err != nil {
		return 0, err
	}

	if len(chunk) < chunkHeaderSize {
		return 0, fmt.Errorf("Decrypt: truncated chunk header")
	}
	ctLen := int(binary.BigEndian.Uint32(chunk[:chunkHeaderSize]))
	if chunkHeaderSize+ctLen > len(chunk) {
		return 0, fmt.Errorf("Decrypt: chunk data truncated: need %d, have %d", chunkHeaderSize+ctLen, len(chunk))
	}

	plain, decErr := r.enc.Decrypt(chunk[chunkHeaderSize : chunkHeaderSize+ctLen])
	if decErr != nil {
		return 0, fmt.Errorf("Decrypt: %s", decErr)
	}

	if r.skip > 0 {
		skip := r.skip
		r.skip = 0
		if skip >= int64(len(plain)) {
			return 0, io.EOF
		}
		plain = plain[skip:]

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Re-upload or re-sync the object from a healthy replica (juicefs sync with --check-new/--check-all)
  2. Verify the object size in the object store matches expectation; a size not congruent with chunk layout indicates truncation
  3. If the read offset can exceed object size, clamp reads to the object length returned by Head before reading
  4. Check for interrupted juicefs gc/sync jobs and re-run them to repair partial copies
Defensive patterns

Strategy: try-catch

Validate before calling

if off >= objSize { return io.EOF } // avoid reading past a truncated object

Try / catch

n, err := r.Read(buf)
if err != nil && strings.Contains(err.Error(), "truncated chunk header") {
	// object truncated: re-upload or re-sync from replica
}

Prevention

When it happens

Trigger: Calling Read on a chunkedEncryptedObject whose source object ends (or errors with io.ErrUnexpectedEOF) before even 4 bytes of a chunk header are available — e.g. reading past a truncated object or an empty/corrupt object.

Common situations: Object truncated by an interrupted upload or partial sync; reading an object written by a non-chunked writer; bucket contents manually edited; offset beyond actual object size served as a fresh read.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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