siyuan-note/siyuan · error

invalid encrypted asset chunk size

Error message

invalid encrypted asset chunk size

What it means

Each chunk in the encrypted asset stream is prefixed with a big-endian uint32 ciphertext length. This error is thrown when a chunk's declared size is 0 or exceeds encryptedAssetChunkMaxCiphertextSize, so the stream's chunk framing is invalid and decryption cannot safely proceed.

Source

Thrown at kernel/model/crypto.go:2452

	aadPrefix := "siyuan:asset:" + boxID + ":assets/" + diskName
	plainMetadata, decryptErr := util.DecryptWithAAD(assetKey, encryptedMetadata, []byte(aadPrefix+":metadata"))
	if decryptErr != nil {
		return "", decryptErr
	}
	defer zeroAndClear(plainMetadata)
	metadata, err := parseEncryptedAssetMetadata(plainMetadata)
	if err != nil {
		return "", err
	}

	var written int64
	for chunkIndex := uint64(0); chunkIndex < metadata.Chunks; chunkIndex++ {
		var encryptedSize uint32
		if err = binary.Read(reader, binary.BigEndian, &encryptedSize); err != nil {
			return "", err
		}
		if encryptedSize == 0 || encryptedSize > encryptedAssetChunkMaxCiphertextSize {
			return "", errors.New("invalid encrypted asset chunk size")
		}
		encryptedChunk := make([]byte, int(encryptedSize))
		if _, err = io.ReadFull(reader, encryptedChunk); err != nil {
			return "", err
		}
		aad := encryptedAssetChunkAAD(aadPrefix, metadata.ContainerID, chunkIndex)
		if metadata.Spec == encryptedAssetLegacySpec {
			aad = []byte(fmt.Sprintf("%s:content:%d", aadPrefix, chunkIndex))
		}
		plainChunk, chunkErr := util.DecryptWithAAD(
			assetKey,
			encryptedChunk,
			aad,
		)
		if chunkErr != nil {
			return "", chunkErr
		}
		expectedSize := int64(encryptedAssetChunkSize)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Restore the asset from backup or re-transfer it; the stream framing is corrupt and cannot be repaired in place
  2. Re-encrypt the original plaintext asset with the current version if available
  3. Check whether the file was written by an older format version with a different encryptedAssetChunkSize and re-encrypt through that version
  4. Verify the file size matches what metadata.Chunks implies to detect truncation
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check: file length should fit header + metadata + chunks*(4+len) + trailer
fi, err := f.Stat()
if err != nil { return err }
if fi.Size() < int64(8+metaSize+4) { return fmt.Errorf("file too small for chunk framing") }

Prevention

When it happens

Trigger: DecryptAssetToWriter iterates metadata.Chunks chunks and reads each length prefix; any chunk length of 0 or above the max ciphertext size (e.g. from truncation, byte-shifted stream data, or mismatched chunk size between write and read versions) raises this error.

Common situations: A sync client uploading/downloading a partially transferred file; a modified chunk size constant between format versions making old files unreadable; manual byte-level edits of the encrypted blob.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/aca5142e5aa3c534. Report an issue: GitHub.