siyuan-note/siyuan · error
imported notebook [%s] contains encrypted payload without id
Error message
imported notebook [%s] contains encrypted payload without identity
What it means
Thrown by validateImportedNotebookIdentities when no encryption identity was resolved (boxCrypt == nil after checking conf.json and backup), but the directory walk detected files with encrypted-notebook data headers. This means the notebook contains encrypted .sy files but has no credentials to decrypt them — the data would be permanently inaccessible after import. The import is refused to protect the user from importing unrecoverable data.
Source
Thrown at kernel/model/import.go:1090
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
}
payloadFound, payloadErr := hasEncryptedNotebookPayloadAtPath(boxDir)
if payloadErr != nil {
return nil, fmt.Errorf("inspect imported notebook [%s] failed: %w", boxID, payloadErr)
}
if boxCrypt == nil && payloadFound {
return nil, fmt.Errorf("imported notebook [%s] contains encrypted payload without identity", boxID)
}
if boxCrypt == nil {
continue
}
if err = validateBoxEncryption(boxCrypt); err != nil {
return nil, fmt.Errorf("invalid imported notebook identity [%s]: %w", boxID, err)
}
if filelock.IsExist(filepath.Join(util.DataDir, boxID)) && IsEncryptedBox(boxID) {
return nil, fmt.Errorf("refuse to overwrite existing encrypted notebook [%s]", boxID)
}
encryptedBoxIDs = append(encryptedBoxIDs, boxID)
}
return encryptedBoxIDs, nil
}
func ImportData(zipPath string) (err error) {
util.PushEndlessProgress(Conf.Language(73))View on GitHub (pinned to 251596fc0d)
Solutions
- Re-export the Data.zip ensuring the complete .siyuan/ directory (including encryption identity files) is included.
- If the encryption identity is permanently lost, the encrypted data cannot be recovered — obtain a fresh export from the source.
- Remove the encrypted notebook directory from the Data.zip if it is not needed, then import the rest.
- If you have the master password and a separate identity backup, manually restore the identity files into the .siyuan/ directory before importing.
Defensive patterns
Strategy: validation
Validate before calling
// Check for orphaned encrypted payload before importing
func checkOrphanedPayload(tmpDataPath, boxID string) error {
boxDir := filepath.Join(tmpDataPath, boxID)
confPath := filepath.Join(boxDir, ".siyuan", "conf.json")
backupPath := filepath.Join(boxDir, ".siyuan", notebookCryptoBackupFilename)
hasIdentity := false
if filelock.IsExist(confPath) {
data, _ := filelock.ReadFile(confPath)
bc := conf.NewBoxConf()
if gulu.JSON.UnmarshalJSON(data, bc) == nil && bc.Encrypted && bc.BoxCrypt != nil {
hasIdentity = true
}
}
if !hasIdentity && filelock.IsExist(backupPath) {
hasIdentity = true
}
if !hasIdentity {
found, _ := hasEncryptedNotebookPayloadAtPath(boxDir)
if found {
return fmt.Errorf("notebook %s has encrypted files but no identity", boxID)
}
}
return nil
} Try / catch
encryptedBoxIDs, err := validateImportedNotebookIdentities(tmpDataPath)
if err != nil {
if strings.Contains(err.Error(), "encrypted payload without identity") {
// Data is unrecoverable without identity — must re-export with identity files
return fmt.Errorf("cannot import: encrypted data has no identity — re-export with .siyuan/ directory")
}
} Prevention
- Always include the complete .siyuan/ directory when exporting Data.zip.
- Do not selectively extract files from the Data.zip — use the complete archive.
- If the identity is permanently lost, the encrypted data cannot be imported.
- Verify the archive includes identity files for any encrypted notebooks before importing.
When it happens
Trigger: Calling validateImportedNotebookIdentities where boxCrypt is nil (no encryption identity from conf.json or backup) AND hasEncryptedNotebookPayloadAtPath returns payloadFound == true. The check is at import.go:1089-1091.
Common situations: Exporting only the notebook data directory without the .siyuan/ identity files. Partial backup where encryption identity was stored separately and not included. Data corruption that removed identity files while leaving encrypted content. Manual extraction and re-zipping that dropped hidden directories.
Related errors
- encrypted notebook [%s] has no valid identity
- read imported notebook conf [%s] failed: %w
- parse imported notebook conf [%s] failed: %w
- invalid imported notebook identity [%s]: %w
- notebook [%s] has conflicting normal and encrypted identitie
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/d4a49597ab7981b6.
Report an issue: GitHub.