siyuan-note/siyuan · error

Argon2id KeyLength must be 32

Error message

Argon2id KeyLength must be 32

What it means

ValidateArgon2Params checks Argon2id KDF parameters before deriving keys for encrypted notebooks. The derived key length is a fixed format constant: exactly 32 bytes (AES-256). Any configured KeyLength other than 32 is rejected because it would produce keys incompatible with the on-disk encryption format, so the library refuses with this error before any derivation happens.

Solutions

  1. Set KeyLength to exactly 32 in the Argon2Params before calling — it is not user-tunable
  2. If it comes from an imported backup/config, correct the keyLength field to 32 (or re-export the backup with the official tooling)
  3. If the config is corrupt and no valid backup exists, restore from a notebook crypto backup that authenticates; never regenerate salts to work around it
  4. In code, always construct params via the existing helpers (deriveKEK etc.) so KeyLength is fixed at 32

Example fix

// before
p := util.Argon2Params{Memory: 128 * 1024, Iterations: 3, KeyLength: 64}
_, err := util.ValidateArgon2Params(p) // error
// after
p := util.Argon2Params{Memory: 128 * 1024, Iterations: 3, KeyLength: 32}
_, err := util.ValidateArgon2Params(p) // ok
Defensive patterns

Strategy: validation

Validate before calling

if p.KeyLength != 32 { return fmt.Errorf("KeyLength must be 32, got %d", p.KeyLength) }
// then call util.ValidateArgon2Params(p)

Type guard

func hasValidKeyLength(p util.Argon2Params) bool { return p.KeyLength == 32 }

Try / catch

if _, err := util.ValidateArgon2Params(p); err != nil && strings.Contains(err.Error(), "KeyLength must be 32") {
    p.KeyLength = 32 // format constant; retry
}

Prevention

When it happens

Trigger: Calling ValidateArgon2Params (via deriveKEK, EnableEncryptedNotebook, ImportNotebookCryptoBackup, or notebook crypto backup/restore paths) with an Argon2Params struct whose KeyLength field is not 32 — e.g. a hand-edited backup config, a migrated config from tooling, or a constructed params struct that left KeyLength at 0/default.

Common situations: Manually editing the notebook crypto settings JSON and changing keyLength; importing a crypto backup produced by an incompatible/older or third-party tool; a bug in code that builds Argon2Params without setting KeyLength=32; corruption of the stored config.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — 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/5c79639a22a39629. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/kdf.go:65

	Parallelism uint8  `json:"parallelism"` // 并行线程数
	KeyLength   uint32 `json:"keyLength"`   // 输出密钥长度,单位字节
}

// DefaultArgon2Params 返回 OWASP 2023 推荐的 Argon2id 参数。
func DefaultArgon2Params() Argon2Params {
	return Argon2Params{
		Memory:      64 * 1024,
		Iterations:  3,
		Parallelism: 4,
		KeyLength:   32,
	}
}

// ValidateArgon2Params 校验 Argon2id 参数是否在合理范围内,防止恶意备份设置极大内存导致 OOM,
// 或过弱参数降低安全性。
func ValidateArgon2Params(p Argon2Params) (Argon2Params, error) {
	if p.KeyLength != 32 {
		return p, errors.New("Argon2id KeyLength must be 32")
	}
	if p.Memory < 64*1024 {
		return p, errors.New("Argon2id Memory too low (minimum 64 MB)")
	}
	if p.Memory > 256*1024 {
		return p, errors.New("Argon2id Memory too high (maximum 256 MB)")
	}
	if p.Iterations < 3 {
		return p, errors.New("Argon2id Iterations too low (minimum 3)")
	}
	if p.Iterations > 10 {
		return p, errors.New("Argon2id Iterations too high (maximum 10)")
	}
	if p.Parallelism == 0 || p.Parallelism > 16 {
		return p, errors.New("Argon2id Parallelism must be between 1 and 16")
	}
	return p, nil
}

View on GitHub (pinned to 9f775e8a12)