slackhq/nebula · error
no cipher state available to encrypt
Error message
no cipher state available to encrypt
What it means
The FIPS-140 GCM implementation's EncryptDanger has the same nil-receiver guard: a nil *aeadGCMFIPS140Cipher has no AEAD to seal with, so it returns this error instead of panicking, and also enforces the same RejectAfterMessages nonce ceiling.
Source
Thrown at noiseutil/fips140.go:118
func (c *aeadGCMFIPS140Cipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
if !c.ready {
c.init(nonce)
}
return c.AEAD.Seal(dst, nonce, plaintext, additionalData)
}
func (c *aeadGCMFIPS140Cipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte {
return c.Seal(out, aeadGCMFIPS140CipherNonce(n), plaintext, ad)
}
func (c *aeadGCMFIPS140Cipher) Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) {
return c.Open(out, aeadGCMFIPS140CipherNonce(n), ciphertext, ad)
}
func (c *aeadGCMFIPS140Cipher) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
if c == nil {
return nil, errors.New("no cipher state available to encrypt")
}
if n >= RejectAfterMessages {
return nil, ErrMessageCounterExhausted
}
binary.BigEndian.PutUint64(nb[4:], n)
out = c.Seal(out, nb, plaintext, ad)
return out, nil
}
func (c *aeadGCMFIPS140Cipher) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
if c == nil {
return []byte{}, nil
}
binary.BigEndian.PutUint64(nb[4:], n)
return c.Open(out, nb, ciphertext, ad)
}
func (c *aeadGCMFIPS140Cipher) Overhead() int {View on GitHub (pinned to dd8f660c0a)
Solutions
- Ensure the handshake completes and the FIPS GCM cipher is constructed before any EncryptDanger call.
- Add a nil check on the cipher before sending in FIPS mode.
- Rekey if the nonce has reached RejectAfterMessages.
Example fix
// before
out, err := c.EncryptDanger(out, ad, plaintext, n, nb) // c may be nil
// after
if c == nil { return nil, errors.New("FIPS GCM cipher not initialized") } Defensive patterns
Strategy: type-guard
Validate before calling
if c == nil {
return errors.New("FIPS GCM cipher not initialized")
} Type guard
func fipsCipherReady(c *aeadGCMFIPS140Cipher) bool { return c != nil } Try / catch
out, err := c.EncryptDanger(out, ad, plaintext, n, nb)
if err != nil {
// nil state: re-run handshake; exhausted: rekey
} Prevention
- Verify FIPS mode initialization completes before serving traffic.
- Fail startup if the FIPS cipher cannot be constructed.
- Log handshake completion before enabling the data path.
When it happens
Trigger: EncryptDanger called on a nil aeadGCMFIPS140Cipher (FIPS mode cipher never initialized because handshake failed or FIPS mode setup was skipped), or the nonce n reaching RejectAfterMessages.
Common situations: FIPS-140 mode enabled but cipher construction failed upstream, handshake not completed before sending data traffic in a FIPS-restricted deployment.
Related errors
- no cipher state available to encrypt
- no cipher state available to encrypt
- ErrIncompleteHandshake
- ErrMachineFailed
- ErrMissingContent
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/209fc07104963749.
Report an issue: GitHub.