getsops/sops · error

cannot split an empty secret

Error message

cannot split an empty secret

What it means

Split() cannot derive shares from a zero-length secret; each share is built per secret byte, so an empty secret produces meaningless output. The library rejects it explicitly.

Source

Thrown at shamir/shamir.go:209

// 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)
		out[idx][len(secret)] = uint8(idx) + 1
	}

	// Construct a random polynomial for each byte of the secret.
	// Because we are using a field of size 256, we can only represent
	// a single byte as the intercept of the polynomial, so we must

View on GitHub (pinned to 13442bb981)

Solutions

  1. Ensure the secret is generated/populated before calling Split (check len(secret) > 0).
  2. Fix the upstream key-generation function returning empty bytes.
  3. Add a caller-side length check to fail with clearer context.

Example fix

// before
var key []byte
shares, err := shamir.Split(key, 5, 3)
// after
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil { return err }
shares, err := shamir.Split(key, 5, 3)
Defensive patterns

Strategy: validation

Validate before calling

if len(secret) == 0 {
    return fmt.Errorf("secret is empty; check key generation")
}

Prevention

When it happens

Trigger: Calling Split with an empty (nil or len 0) secret byte slice, often from an empty key-generation result or an unfilled buffer.

Common situations: A crypto/rand or key-service call returned an empty slice upstream, or a variable was declared but never populated before splitting.

Related errors


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