slackhq/nebula · error
incompatible Argon2 version: %d
Error message
incompatible Argon2 version: %d
What it means
deriveKey checks that the Argon2Parameters version matches the argon2.Version the library was compiled against (argon2id, version 0x13). A mismatch means the stored/constructed KDF parameters came from an incompatible Argon2 variant (argon2i/argon2d or a different version byte).
Source
Thrown at cert/crypto.go:131
params.salt = make([]byte, 32)
if _, err := rand.Read(params.salt); err != nil {
return nil, err
}
}
// keySize of 32 bytes will result in AES-256 encryption
key, err := deriveKey(passphrase, 32, params)
if err != nil {
return nil, err
}
return key, nil
}
// Derives a key from a passphrase using Argon2id
func deriveKey(passphrase []byte, keySize uint32, params *Argon2Parameters) ([]byte, error) {
if params.version != argon2.Version {
return nil, fmt.Errorf("incompatible Argon2 version: %d", params.version)
}
if params.salt == nil {
return nil, fmt.Errorf("salt must be set in argon2Parameters")
} else if len(params.salt) < 16 {
return nil, fmt.Errorf("salt must be at least 128 bits")
}
key := argon2.IDKey(passphrase, params.salt, params.Iterations, params.Memory, params.Parallelism, keySize)
return key, nil
}
// Prepends nonce to ciphertext
func joinNonceCiphertext(nonce []byte, ciphertext []byte) []byte {
return append(nonce, ciphertext...)
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Create parameters with NewArgon2Parameters(memory, parallelism, iterations) so the correct version is set.
- If the blob came from another tool, re-encrypt the key with this library's EncryptAndMarshalSigningPrivateKey.
- Align library versions between encrypting and decrypting parties.
Example fix
// before
params := &cert.Argon2Parameters{Memory: 9k...} // version left zero-value
// after
params := cert.NewArgon2Parameters(9*1024, 1, 4) // sets version = argon2.Version Defensive patterns
Strategy: validation
Validate before calling
// always construct parameters via the constructor so version is set correctly params := cert.NewArgon2Parameters(9*1024, 1, 4) // version := argon2.Version (0x13)
Try / catch
if err != nil && strings.Contains(err.Error(), "incompatible Argon2 version") {
return fmt.Errorf("encrypted key was produced with an incompatible Argon2 variant; re-encrypt with this library")
} Prevention
- Never construct Argon2Parameters literals manually; use NewArgon2Parameters.
- Re-encrypt keys created by other tools or forks before use.
- Keep the golang.org/x/crypto/argon2 dependency consistent across services.
When it happens
Trigger: Decrypting (or deriving with) parameters whose params.version was set manually or deserialized from data produced by a different Argon2 version — note Argon2Parameters.version is unexported, so this only happens via NewArgon2Parameters mishandling or crafted/edited encrypted blobs.
Common situations: Hand-editing encrypted key metadata, cross-version decryption between forks that used different argon2 libraries, or tests constructing Argon2Parameters without NewArgon2Parameters.
Related errors
- salt must be set in argon2Parameters
- no cipher state available to encrypt
- no cipher state available to encrypt
- invalid AES-256 key length (%d) - cowardly refusing to encry
- invalid passphrase or corrupt private key
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/8bffe50013e092c2.
Report an issue: GitHub.