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

  1. Check the kernel log for the wrapped cause from readBoxEncryptionFile/validateBoxEncryption to see which field or check failed.
  2. Restore the notebook's .siyuan encryption backup file from the original workspace, snapshot, or sync history, then retry the import.
  3. Re-export the notebook from the source workspace where it opens successfully, and import that fresh archive.
  4. 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

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


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)