slackhq/nebula · error

-argon-iterations must be be greater than 0 and no more than

Error message

-argon-iterations must be be greater than 0 and no more than %d

What it means

Argon2 iteration count must be a positive value no greater than MaxUint32. Zero/negative or oversized iteration counts cannot be given to the Argon2 KDF, so the unmarshalling step rejects them. (Note the message text reuses the CLI flag name '-argon-iterations'.)

Source

Thrown at cert/crypto.go:240

		},
		Ciphertext: rned.Ciphertext,
	}

	return &ned, nil
}

func unmarshalArgon2Parameters(params *RawNebulaArgon2Parameters) (*Argon2Parameters, error) {
	if params.Version < math.MinInt32 || params.Version > math.MaxInt32 {
		return nil, fmt.Errorf("Argon2Parameters Version must be at least %d and no more than %d", math.MinInt32, math.MaxInt32)
	}
	if params.Memory <= 0 || params.Memory > math.MaxUint32 {
		return nil, fmt.Errorf("Argon2Parameters Memory must be be greater than 0 and no more than %d KiB", uint32(math.MaxUint32))
	}
	if params.Parallelism <= 0 || params.Parallelism > math.MaxUint8 {
		return nil, fmt.Errorf("Argon2Parameters Parallelism must be be greater than 0 and no more than %d", math.MaxUint8)
	}
	if params.Iterations <= 0 || params.Iterations > math.MaxUint32 {
		return nil, fmt.Errorf("-argon-iterations must be be greater than 0 and no more than %d", uint32(math.MaxUint32))
	}

	return &Argon2Parameters{
		version:     params.Version,
		Memory:      params.Memory,
		Parallelism: uint8(params.Parallelism),
		Iterations:  params.Iterations,
		salt:        params.Salt,
	}, nil

}

// DecryptAndUnmarshalSigningPrivateKey will try to pem decode and decrypt an Ed25519/ECDSA private key with
// the given passphrase, returning any other bytes b or an error on failure
func DecryptAndUnmarshalSigningPrivateKey(passphrase, b []byte) (Curve, []byte, []byte, error) {
	var curve Curve

	k, r := pem.Decode(b)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Set Iterations to a positive value (nebula default is 1) wherever the parameters are serialized
  2. Re-encrypt via EncryptAndMarshalSigningPrivateKey / EncryptAndMarshalCert so all Argon2 fields are populated correctly
  3. Treat failing blobs from untrusted sources as invalid and refuse them

Example fix

// before
raw := &cert.RawNebulaArgon2Parameters{Version: 19, Memory: 2097152, Parallelism: 4} // Iterations unset
// after
raw := &cert.RawNebulaArgon2Parameters{Version: 19, Memory: 2097152, Parallelism: 4, Iterations: 1, Salt: salt}
Defensive patterns

Strategy: validation

Validate before calling

if params.Iterations <= 0 || params.Iterations > math.MaxUint32 { return fmt.Errorf("iterations must be in (0, %d]", uint32(math.MaxUint32)) }

Try / catch

ned, err := cert.UnmarshalNebulaEncryptedData(b)
if err != nil {
    if strings.Contains(err.Error(), "argon-iterations must be") { /* fix producing side or reject blob */ }
    return err
}

Prevention

When it happens

Trigger: Deserializing RawNebulaArgon2Parameters with Iterations <= 0 (usually 0 from an unset proto3 field) or Iterations > math.MaxUint32 in data passed to UnmarshalNebulaEncryptedData.

Common situations: Hand-built messages omitting Iterations; corrupted encrypted-data blobs from untrusted sources; tooling writing iteration counts in incompatible units causing overflow-scale values.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/2b2af60b4eb35d26. Report an issue: GitHub.