getsops/sops · error

threshold must be at least 2

Error message

threshold must be at least 2

What it means

A threshold of 1 would mean a single share reconstructs the secret, which defeats the purpose of Shamir secret sharing; Split() enforces threshold >= 2.

Source

Thrown at shamir/shamir.go:203

	// Addition in GF(2^8) equals XOR:
	return a ^ b
}

// Split takes an arbitrarily long secret and generates a `parts`
// number of shares, `threshold` of which are required to reconstruct
// the secret. The parts and threshold must be at least 2, and less
// than 256. The returned shares are each one byte longer than the secret
// as they attach a tag used to reconstruct the secret.
func Split(secret []byte, parts, threshold int) ([][]byte, error) {
	// Sanity check the input
	if parts < threshold {
		return nil, fmt.Errorf("parts cannot be less than threshold")
	}
	if parts > 255 {
		return nil, fmt.Errorf("parts cannot exceed 255")
	}
	if threshold < 2 {
		return nil, fmt.Errorf("threshold must be at least 2")
	}
	if threshold > 255 {
		return nil, fmt.Errorf("threshold cannot exceed 255")
	}
	if len(secret) == 0 {
		return nil, fmt.Errorf("cannot split an empty secret")
	}

	// Allocate the output array, initialize the final byte
	// of the output with the offset. The representation of each
	// output is {y1, y2, .., yN, x}.
	out := make([][]byte, parts)
	for idx := range out {
		// Store the x coordinate for each part as its last byte
		// Add 1 to the xCoordinate because if the x coordinate is 0,
		// then the result of evaluating the polynomial at that point
		// will be our secret
		out[idx] = make([]byte, len(secret)+1)

View on GitHub (pinned to 13442bb981)

Solutions

  1. Pass threshold >= 2.
  2. Fix the configuration/source producing a 0 or 1 threshold.
  3. Validate quorum settings before calling Split.

Example fix

// before
shares, err := shamir.Split(secret, 5, 1)
// after
shares, err := shamir.Split(secret, 5, 3)
Defensive patterns

Strategy: validation

Validate before calling

if threshold < 2 {
    return fmt.Errorf("threshold must be at least 2, got %d", threshold)
}

Prevention

When it happens

Trigger: Calling Split(secret, parts, threshold) with threshold < 2, e.g. Split(secret, 5, 1) or threshold 0 from an unset config value.

Common situations: Default-zero config values, tests probing boundary conditions, or misunderstanding that threshold is a minimum quorum of at least 2.

Related errors


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/6896dd99b01a0fb3. Report an issue: GitHub.