siyuan-note/siyuan · error

encrypted asset metadata is too large

Error message

encrypted asset metadata is too large

What it means

Thrown by EncryptAsset when the encrypted metadata blob (the ciphertext of the JSON {originalName, size, chunks}) exceeds encryptedAssetMetadataMaxSize (1 MiB). Since the metadata JSON is tiny, this practically requires an absurdly long originalName (hundreds of thousands of characters) that bloats the ciphertext past the limit.

Source

Thrown at kernel/model/crypto.go:2230

		chunkCount = 1
	}
	metadata, err := json.Marshal(&encryptedAssetMetadata{
		OriginalName: originalName,
		Size:         int64(len(plaintext)),
		Chunks:       chunkCount,
	})
	if err != nil {
		return nil, err
	}
	assetKey := util.DeriveSubKey(dek, "siyuan/asset")
	defer zeroAndClear(assetKey)
	aadPrefix := "siyuan:asset:" + boxID + ":assets/" + diskName
	encryptedMetadata, err := util.EncryptWithAAD(assetKey, metadata, []byte(aadPrefix+":metadata"))
	if err != nil {
		return nil, err
	}
	if len(encryptedMetadata) > encryptedAssetMetadataMaxSize {
		return nil, errors.New("encrypted asset metadata is too large")
	}
	ret := bytes.NewBuffer(make([]byte, 0, len(plaintext)+len(encryptedMetadata)+int(chunkCount)*64+12))
	ret.Write(encryptedAssetMagic)
	if err = binary.Write(ret, binary.BigEndian, uint32(len(encryptedMetadata))); err != nil {
		return nil, err
	}
	ret.Write(encryptedMetadata)
	for chunkIndex := uint64(0); chunkIndex < chunkCount; chunkIndex++ {
		start := int(chunkIndex) * encryptedAssetChunkSize
		end := start + encryptedAssetChunkSize
		if end > len(plaintext) {
			end = len(plaintext)
		}
		encryptedChunk, encryptErr := util.EncryptWithAAD(
			assetKey,
			plaintext[start:end],
			[]byte(fmt.Sprintf("%s:content:%d", aadPrefix, chunkIndex)),
		)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Verify the originalName argument to EncryptAsset is a basename (filepath.Base) and not a full path or file content.
  2. Sanitize or truncate the filename before encryption: use util.FilterFileName and enforce a reasonable max length (e.g., 255 chars).
  3. If you legitimately need huge metadata, raise encryptedAssetMetadataMaxSize in the source — but this changes the on-disk format and breaks compatibility.

Example fix

// before
enc, err := EncryptAsset(boxID, diskName, userInput, dek, data)
// after
name := filepath.Base(userInput)
name = util.FilterFileName(name)
if len(name) > 255 { name = name[:255] }
enc, err := EncryptAsset(boxID, diskName, name, dek, data)
Defensive patterns

Strategy: validation

Validate before calling

// Validate filename length before encrypting
name := filepath.Base(originalName)
name = util.FilterFileName(name)
if len(name) > 255 {
    name = name[:255]
}

Prevention

When it happens

Trigger: EncryptAsset is called with an originalName that is pathologically long, or a future metadata schema change adds large fields. The check caps metadata so decryption can safely allocate bounded buffers.

Common situations: Almost never seen in practice — normal filenames are well under the limit. Could arise from a bug in upstream code that passes a full path or file content instead of a basename to originalName.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/d712f8d0b66cf5fb. Report an issue: GitHub.