{"record":{"id":"aca5142e5aa3c534","repo":"siyuan-note/siyuan","slug":"invalid-encrypted-asset-chunk-size","errorCode":null,"errorMessage":"invalid encrypted asset chunk size","messagePattern":"invalid encrypted asset chunk size","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":2452,"sourceCode":"\taadPrefix := \"siyuan:asset:\" + boxID + \":assets/\" + diskName\n\tplainMetadata, decryptErr := util.DecryptWithAAD(assetKey, encryptedMetadata, []byte(aadPrefix+\":metadata\"))\n\tif decryptErr != nil {\n\t\treturn \"\", decryptErr\n\t}\n\tdefer zeroAndClear(plainMetadata)\n\tmetadata, err := parseEncryptedAssetMetadata(plainMetadata)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar written int64\n\tfor chunkIndex := uint64(0); chunkIndex < metadata.Chunks; chunkIndex++ {\n\t\tvar encryptedSize uint32\n\t\tif err = binary.Read(reader, binary.BigEndian, &encryptedSize); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tif encryptedSize == 0 || encryptedSize > encryptedAssetChunkMaxCiphertextSize {\n\t\t\treturn \"\", errors.New(\"invalid encrypted asset chunk size\")\n\t\t}\n\t\tencryptedChunk := make([]byte, int(encryptedSize))\n\t\tif _, err = io.ReadFull(reader, encryptedChunk); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\taad := encryptedAssetChunkAAD(aadPrefix, metadata.ContainerID, chunkIndex)\n\t\tif metadata.Spec == encryptedAssetLegacySpec {\n\t\t\taad = []byte(fmt.Sprintf(\"%s:content:%d\", aadPrefix, chunkIndex))\n\t\t}\n\t\tplainChunk, chunkErr := util.DecryptWithAAD(\n\t\t\tassetKey,\n\t\t\tencryptedChunk,\n\t\t\taad,\n\t\t)\n\t\tif chunkErr != nil {\n\t\t\treturn \"\", chunkErr\n\t\t}\n\t\texpectedSize := int64(encryptedAssetChunkSize)","sourceCodeStart":2434,"sourceCodeEnd":2470,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/crypto.go#L2434-L2470","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Restore the asset from backup or re-transfer it; the stream framing is corrupt and cannot be repaired in place","Re-encrypt the original plaintext asset with the current version if available","Check whether the file was written by an older format version with a different encryptedAssetChunkSize and re-encrypt through that version","Verify the file size matches what metadata.Chunks implies to detect truncation"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// sanity-check: file length should fit header + metadata + chunks*(4+len) + trailer\nfi, err := f.Stat()\nif err != nil { return err }\nif fi.Size() < int64(8+metaSize+4) { return fmt.Errorf(\"file too small for chunk framing\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Re-download or re-sync files instead of attempting to decrypt obviously truncated ones","Pin the same SiYuan version for write and read when moving encrypted assets between installs"],"tags":["encryption","chunking","corruption"],"backgroundTag":"value-out-of-range","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}