getsops/sops · error

parts must be at least two bytes

Error message

parts must be at least two bytes

What it means

Each share is {y1..yN, x}: at minimum one y value plus the x tag byte, so every share must be at least 2 bytes long. Combine() rejects shorter parts because they carry no reconstructable data.

Source

Thrown at shamir/shamir.go:265

		}
	}

	// Return the encoded secrets
	return out, nil
}

// Combine is used to reverse a Split and reconstruct a secret
// once a `threshold` number of parts are available.
func Combine(parts [][]byte) ([]byte, error) {
	// Verify enough parts provided
	if len(parts) < 2 {
		return nil, fmt.Errorf("less than two parts cannot be used to reconstruct the secret")
	}

	// Verify the parts are all the same length
	firstPartLen := len(parts[0])
	if firstPartLen < 2 {
		return nil, fmt.Errorf("parts must be at least two bytes")
	}
	for i := 1; i < len(parts); i++ {
		if len(parts[i]) != firstPartLen {
			return nil, fmt.Errorf("all parts must be the same length")
		}
	}

	// Create a buffer to store the reconstructed secret
	secret := make([]byte, firstPartLen-1)

	// Buffer to store the samples
	xSamples := make([]uint8, len(parts))
	ySamples := make([]uint8, len(parts))

	// Set the x value for each sample and ensure no x_sample values are the same,
	// otherwise div() can be unhappy
	// Check that we don't have any duplicate parts, that is, two or
	// more parts with the same x coordinate.

View on GitHub (pinned to 13442bb981)

Solutions

  1. Verify each share file/transport preserves the full byte length (base64/hex encode shares for storage/transfer).
  2. Re-collect the corrupted share from a custodian.
  3. Check that raw (non-encoded) share bytes are passed, not transformed values.
  4. Validate len(part) >= 2 and consistent lengths before calling Combine.

Example fix

// before
shares = append(shares, []byte(trimmedLine)) // possibly mangled text
// after
for _, s := range rawShares {
    if len(s) < 2 { return fmt.Errorf("share too short (%d bytes)", len(s)) }
}
secret, err := shamir.Combine(shares)
Defensive patterns

Strategy: validation

Validate before calling

for i, p := range parts {
    if len(p) < 2 {
        return fmt.Errorf("share %d is %d bytes; must be >= 2 (truncated?)", i, len(p))
    }
}

Prevention

When it happens

Trigger: Calling Combine with a part of length 0 or 1 — e.g. truncated file contents, a share string that was trimmed/corrupted, or passing raw secret bytes instead of shares.

Common situations: Shares stored in files that were truncated, whitespace-stripped encodings dropping bytes, or users pasting shares into systems that mangled them (e.g. leading zero bytes lost in decimal conversion).

Related errors


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