siyuan-note/siyuan · critical
invalid imported notebook identity
Error message
invalid imported notebook identity [%s]: %w
What it means
validateImportedNotebookIdentities loads the notebook's encryption backup file (.siyuan/<notebookCryptoBackupFilename>) via readBoxEncryptionFile. If that file exists but is invalid (unreadable, malformed, or failing validateBoxEncryption checks), the function returns 'invalid imported notebook identity [%s]' wrapping the cause, because the imported encrypted notebook's key-envelope identity cannot be established and further use would risk unrecoverable data.
Solutions
- Check the kernel log for the wrapped cause from readBoxEncryptionFile/validateBoxEncryption to see which field or check failed.
- Restore the notebook's .siyuan encryption backup file from the original workspace, snapshot, or sync history, then retry the import.
- Re-export the notebook from the source workspace where it opens successfully, and import that fresh archive.
- Do NOT delete or regenerate the encryption backup/salt — per policy, encrypted data must stay recoverable; if the key material is truly lost, access must be restored from the recovery phrase before re-importing.
Defensive patterns
Strategy: validation
Validate before calling
const backupPath = path.join(boxDir, '.siyuan', notebookCryptoBackupFilename);
if (fs.existsSync(backupPath)) {
const b = JSON.parse(await fs.promises.readFile(backupPath, 'utf8'));
if (!b.salt || !b.nonce || !b.algorithm) throw new Error('incomplete encryption backup');
} Type guard
function isValidBoxEncryption(v) {
return v !== null && typeof v === 'object' && typeof v.salt === 'string' && typeof v.nonce === 'string' && typeof v.algorithm === 'string';
} Try / catch
try {
await importData(src);
} catch (e) {
if (/invalid imported notebook identity/.test(e.msg)) {
console.error('Restore the notebook\'s encryption backup from source workspace/history; do not regenerate salts');
}
throw e;
} Prevention
- Always archive the full .siyuan directory when exporting encrypted notebooks
- Never hand-edit or regenerate encryption backup files or MasterSalt
- Keep source and target SiYuan versions compatible for envelope formats
When it happens
Trigger: ImportData importing a notebook that has an encryption backup file which is corrupt, tampered, an unknown format version, or fails key-derivation parameter validation (e.g. missing/invalid salt, nonce, or algorithm fields).
Common situations: 1) Partial or failed sync/backup left a truncated backup file. 2) Hand-editing of the encryption backup file. 3) Importing data produced by a newer SiYuan version with an envelope format the current kernel cannot validate (version change). 4) Corruption during archive transfer.
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
- encrypted notebook [ ] has no valid identity
- notebook [ ] has conflicting normal and encrypted identities
- 199
- Conf.Language(0)
- Conf.Language(388) with escaped relative path…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/5b3283a0db0145ad.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/import.go:1348
backupPath := filepath.Join(boxDir, ".siyuan", notebookCryptoBackupFilename)
var boxConf *conf.BoxConf
if filelock.IsExist(confPath) {
data, readErr := filelock.ReadFile(confPath)
if readErr != nil {
return nil, fmt.Errorf("read imported notebook conf [%s] failed: %w", boxID, readErr)
}
boxConf = conf.NewBoxConf()
if unmarshalErr := gulu.JSON.UnmarshalJSON(data, boxConf); unmarshalErr != nil {
return nil, fmt.Errorf("parse imported notebook conf [%s] failed: %w", boxID, unmarshalErr)
}
}
var backup *conf.BoxEncryption
if filelock.IsExist(backupPath) {
backup, err = readBoxEncryptionFile(backupPath)
if err != nil {
return nil, fmt.Errorf("invalid imported notebook identity [%s]: %w", boxID, err)
}
}
var boxCrypt *conf.BoxEncryption
if boxConf != nil && boxConf.Encrypted {
if boxConf.BoxCrypt != nil && validateBoxEncryption(boxConf.BoxCrypt) == nil {
boxCrypt = boxConf.BoxCrypt
} else {
boxCrypt = backup
}
if boxCrypt == nil {
return nil, fmt.Errorf("encrypted notebook [%s] has no valid identity", boxID)
}
} else if boxConf != nil && backup != nil {
return nil, fmt.Errorf("notebook [%s] has conflicting normal and encrypted identities", boxID)
} else if backup != nil {
boxCrypt = backup
}View on GitHub (pinned to 9f775e8a12)