cilium/cilium · error
invalid cipher IPsec key SPI: %s
Error message
invalid cipher IPsec key SPI: %s
What it means
cipherKeyFromSlice converts field 2 (index 1, the SPI with a trailing '+' trimmed) to an integer for 6-field cipher-mode key lines. This error means the SPI token is not a valid decimal number.
Source
Thrown at cilium-cli/encrypt/ipsec_rotate_key.go:118
return ipsecKey{}, fmt.Errorf("invalid IPsec key size: %s", parts[4])
}
key := ipsecKey{
spi: spi,
algo: parts[2],
key: parts[3],
size: size,
}
return key, nil
}
func cipherKeyFromSlice(parts []string) (ipsecKey, error) {
if len(parts) != 6 {
return ipsecKey{}, fmt.Errorf("IPsec key invalid [expected parts: 6, actual parts: %d]", len(parts))
}
parts[1] = strings.TrimSuffix(parts[1], "+")
spi, err := strconv.Atoi(parts[1])
if err != nil {
return ipsecKey{}, fmt.Errorf("invalid cipher IPsec key SPI: %s", parts[1])
}
key := ipsecKey{
spi: spi,
algo: parts[2],
key: parts[3],
cipherMode: parts[4],
cipherKey: parts[5],
}
return key, nil
}
const maxIPsecSPI = 16
func (k ipsecKey) rotate() (ipsecKey, error) {
key, err := generateRandomHex(len(k.key))
if err != nil {
return ipsecKey{}, fmt.Errorf("failed to generate authentication key: %w", err)
}View on GitHub (pinned to ac7b90affa)
Solutions
- Ensure field 2 is a decimal SPI, optionally ending in '+' (e.g. '15+'); fix the token or field order.
- Validate the full 6-field layout: spi, auth-algo, auth-key, cipher-mode, cipher-key, size.
- Regenerate the key entry with Cilium's cipher key format and update the secret before rotating.
Example fix
// before "hmac-sha256 abcdef rfc4106(gcm(aes)) 0123456789abcdef 128" // SPI missing // after "15+ hmac-sha256 abcdef rfc4106(gcm(aes)) 0123456789abcdef 128"
Defensive patterns
Strategy: validation
Validate before calling
parts := strings.Fields(keyLine)
if len(parts) != 6 {
return fmt.Errorf("expected 6 fields, got %d", len(parts))
}
if _, err := strconv.Atoi(strings.TrimSuffix(parts[1], "+")); err != nil {
return fmt.Errorf("field 2 must be numeric SPI, got %q", parts[1])
} Type guard
func validCipherKeyLine(line string) bool {
parts := strings.Fields(line)
if len(parts) != 6 { return false }
_, err := strconv.Atoi(strings.TrimSuffix(parts[1], "+"))
return err == nil
} Try / catch
key, err := cipherKeyFromSlice(parts)
if err != nil {
if strings.Contains(err.Error(), "invalid cipher IPsec key SPI") {
// fix SPI token/field order and retry
}
return err
} Prevention
- Keep SPI as the first field: decimal, optional trailing '+'
- Follow exact 6-field order: spi, auth-algo, auth-key, cipher-mode, cipher-key, size
- Validate cipher key lines before storing in the secret
When it happens
Trigger: The first field pair of a cipher key line is malformed: e.g. 'abc+ hmac-sha256 ...' or 'hmac-sha256 rfc4106(gcm(aes)) ...' with the SPI field missing/shifted, so Atoi fails after trimming '+'.
Common situations: Corrupted or hand-edited cipher key secrets; field order mistakes when constructing 6-field keys manually (someone put the algorithm first); partial paste that dropped the SPI.
Related errors
- invalid IPsec key SPI: %s
- invalid IPsec key size: %s
- IPsec key invalid [expected parts: 6, actual parts: %d]
- failed to rotate IPsec key: %w
- IPsec key has unsupported format
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/af466bd831a0100d.
Report an issue: GitHub.