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

  1. Re-export the Data.zip ensuring the complete .siyuan/ directory (including encryption identity files) is included.
  2. If the encryption identity is permanently lost, the encrypted data cannot be recovered — obtain a fresh export from the source.
  3. Remove the encrypted notebook directory from the Data.zip if it is not needed, then import the rest.
  4. 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

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


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