{"record":{"id":"209fc07104963749","repo":"slackhq/nebula","slug":"no-cipher-state-available-to-encrypt-209fc0","errorCode":null,"errorMessage":"no cipher state available to encrypt","messagePattern":"no cipher state available to encrypt","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"noiseutil/fips140.go","lineNumber":118,"sourceCode":"\nfunc (c *aeadGCMFIPS140Cipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\tif !c.ready {\n\t\tc.init(nonce)\n\t}\n\treturn c.AEAD.Seal(dst, nonce, plaintext, additionalData)\n}\n\nfunc (c *aeadGCMFIPS140Cipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte {\n\treturn c.Seal(out, aeadGCMFIPS140CipherNonce(n), plaintext, ad)\n}\n\nfunc (c *aeadGCMFIPS140Cipher) Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) {\n\treturn c.Open(out, aeadGCMFIPS140CipherNonce(n), ciphertext, ad)\n}\n\nfunc (c *aeadGCMFIPS140Cipher) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {\n\tif c == nil {\n\t\treturn nil, errors.New(\"no cipher state available to encrypt\")\n\t}\n\tif n >= RejectAfterMessages {\n\t\treturn nil, ErrMessageCounterExhausted\n\t}\n\tbinary.BigEndian.PutUint64(nb[4:], n)\n\tout = c.Seal(out, nb, plaintext, ad)\n\treturn out, nil\n}\n\nfunc (c *aeadGCMFIPS140Cipher) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {\n\tif c == nil {\n\t\treturn []byte{}, nil\n\t}\n\tbinary.BigEndian.PutUint64(nb[4:], n)\n\treturn c.Open(out, nb, ciphertext, ad)\n}\n\nfunc (c *aeadGCMFIPS140Cipher) Overhead() int {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/noiseutil/fips140.go#L100-L136","documentation":"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.","triggerScenarios":"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.","commonSituations":"FIPS-140 mode enabled but cipher construction failed upstream, handshake not completed before sending data traffic in a FIPS-restricted deployment.","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."],"exampleFix":"// before\nout, err := c.EncryptDanger(out, ad, plaintext, n, nb) // c may be nil\n// after\nif c == nil { return nil, errors.New(\"FIPS GCM cipher not initialized\") }","handlingStrategy":"type-guard","validationCode":"if c == nil {\n    return errors.New(\"FIPS GCM cipher not initialized\")\n}","typeGuard":"func fipsCipherReady(c *aeadGCMFIPS140Cipher) bool { return c != nil }","tryCatchPattern":"out, err := c.EncryptDanger(out, ad, plaintext, n, nb)\nif err != nil {\n    // nil state: re-run handshake; exhausted: rekey\n}","preventionTips":["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."],"tags":["noise","fips140","aesgcm","nil-state"],"backgroundTag":"uninitialized-cipher-state","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}