getsops/sops · error

parts cannot be less than threshold

Error message

parts cannot be less than threshold

What it means

Split() requires the total number of parts to be greater than or equal to the threshold; a threshold above the part count is mathematically impossible to satisfy. The library validates this up front and rejects the call.

Source

Thrown at shamir/shamir.go:197

	return accumulator
}

// add combines two numbers in GF(2^8)
// This can also be used for subtraction since it is symmetric.
func add(a, b uint8) uint8 {
	// 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)

View on GitHub (pinned to 13442bb981)

Solutions

  1. Pass parts >= threshold (typically parts == threshold).
  2. Swap the arguments if they were reversed.
  3. Clamp or validate inputs at the call site before invoking Split.

Example fix

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

Strategy: validation

Validate before calling

if parts < threshold {
    return fmt.Errorf("parts (%d) must be >= threshold (%d)", parts, threshold)
}

Prevention

When it happens

Trigger: Calling Split(secret, parts, threshold) with parts < threshold, e.g. Split(secret, 3, 5).

Common situations: Swapping the arguments by mistake, computing threshold from configuration while parts comes from a smaller replica count, or copy-pasted unit-test values.

Related errors


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