slackhq/nebula · error
encoded Argon2Parameters was nil
Error message
encoded Argon2Parameters was nil
What it means
Within EncryptionMetadata, the Argon2Parameters sub-message must be present; it defines how the passphrase is stretched into the AES key. When the decoded message has EncryptionMetadata but a nil Argon2Parameters, the library cannot derive the key and fails with this error.
Source
Thrown at cert/crypto.go:210
// UnmarshalNebulaEncryptedData will unmarshal a protobuf byte representation of a nebula cert into its
// protobuf-generated struct.
func UnmarshalNebulaEncryptedData(b []byte) (*NebulaEncryptedData, error) {
if len(b) == 0 {
return nil, fmt.Errorf("nil byte array")
}
var rned RawNebulaEncryptedData
err := proto.Unmarshal(b, &rned)
if err != nil {
return nil, err
}
if rned.EncryptionMetadata == nil {
return nil, fmt.Errorf("encoded EncryptionMetadata was nil")
}
if rned.EncryptionMetadata.Argon2Parameters == nil {
return nil, fmt.Errorf("encoded Argon2Parameters was nil")
}
params, err := unmarshalArgon2Parameters(rned.EncryptionMetadata.Argon2Parameters)
if err != nil {
return nil, err
}
ned := NebulaEncryptedData{
EncryptionMetadata: NebulaEncryptionMetadata{
EncryptionAlgorithm: rned.EncryptionMetadata.EncryptionAlgorithm,
Argon2Parameters: *params,
},
Ciphertext: rned.Ciphertext,
}
return &ned, nil
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Populate Argon2Parameters (version, memory, parallelism, iterations, salt) in EncryptionMetadata before marshalling on the encrypting side
- Re-encrypt using EncryptAndMarshalSigningPrivateKey / EncryptAndMarshalCert which always set Argon2Parameters
- If the data came from another tool, confirm it writes the full nebula encrypted-data format
Example fix
// before
meta := &cert.EncryptionMetadata{Nonce: nonce}
// after
meta := &cert.EncryptionMetadata{Nonce: nonce, Argon2Parameters: &cert.RawNebulaArgon2Parameters{Version: argon2.Version, Memory: 2*1024*1024, Parallelism: 4, Iterations: 1, Salt: salt}} Defensive patterns
Strategy: type-guard
Validate before calling
var rned cert.RawNebulaEncryptedData
proto.Unmarshal(b, &rned)
if rned.EncryptionMetadata != nil && rned.EncryptionMetadata.Argon2Parameters == nil { return fmt.Errorf("Argon2Parameters missing") } Type guard
func hasArgon2Params(b []byte) bool {
var r cert.RawNebulaEncryptedData
if proto.Unmarshal(b, &r) != nil { return false }
return r.EncryptionMetadata != nil && r.EncryptionMetadata.Argon2Parameters != nil
} Try / catch
ned, err := cert.UnmarshalNebulaEncryptedData(b)
if err != nil {
if strings.Contains(err.Error(), "Argon2Parameters was nil") { /* incomplete metadata - re-encrypt */ }
return err
} Prevention
- Populate Argon2Parameters whenever building EncryptionMetadata
- Prefer library encrypt helpers over manual serialization
- Round-trip test: marshal then unmarshal before storing artifacts
When it happens
Trigger: Calling UnmarshalNebulaEncryptedData on data whose EncryptionMetadata was serialized without its Argon2Parameters field set (proto3 omits empty sub-messages), e.g. a partially populated NebulaEncryptedData built by hand or by an incomplete external implementation.
Common situations: Hand-assembling EncryptionMetadata with only the nonce; an external tool serializing a subset of fields; truncation of the message dropping the sub-message field.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- encoded EncryptionMetadata was nil
- Argon2Parameters Version must be at least %d and no more tha
- encoded Details was nil
- salt must be at least 128 bits
- nil byte array
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/b9d936e36ccf8eb1.
Report an issue: GitHub.