ginuerzh/gost · error
ciphertext too short
Error message
ciphertext too short
What it means
decrypt for QUIC packets requires the ciphertext blob to carry at least a GCM nonce prefix; if the received datagram is shorter than gcm.NonceSize(), there is no room for the nonce and authentication cannot proceed, so it fails early with this error.
Source
Thrown at quic.go:333
}
return gcm.Seal(nonce, nonce, data, nil), nil
}
func (conn *quicCipherConn) decrypt(data []byte) ([]byte, error) {
c, err := aes.NewCipher(conn.key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
nonceSize := gcm.NonceSize()
if len(data) < nonceSize {
return nil, errors.New("ciphertext too short")
}
nonce, ciphertext := data[:nonceSize], data[nonceSize:]
return gcm.Open(nil, nonce, ciphertext, nil)
}
func tlsConfigQUICALPN(tlsConfig *tls.Config) *tls.Config {
if tlsConfig == nil {
panic("quic: tlsconfig is nil")
}
tlsConfigQUIC := tlsConfig.Clone()
tlsConfigQUIC.NextProtos = []string{"http/3", "quic/v1"}
return tlsConfigQUIC
}
View on GitHub (pinned to a33fdbf4c9)
Solutions
- Verify the peer is actually the expected QUIC service using the same key/encryption scheme
- Check network path for datagram truncation (MTU, buggy NAT, fragmentation)
- Log and drop the offending datagram; a single bad packet doesn't require reconnecting
- Confirm both sides use the same cipher configuration (nonce size)
Example fix
// before
n, addr, err := conn.ReadFrom(buf) // assume all data is decryptable
// after
n, addr, err := conn.ReadFrom(buf)
if err != nil { continue }
if n < gcmStandardNonceSize { continue } // drop too-short packets before decrypt Defensive patterns
Strategy: validation
Validate before calling
if n < gcmStandardNonceSize {
continue // drop too-short datagram before decrypting
} Try / catch
data, err := decrypt(buf[:n])
if err != nil {
log.Log("dropping undecryptable packet:", err)
continue
} Prevention
- Verify peer encryption config matches (same key/cipher)
- Firewall the QUIC port from random internet UDP noise
- Monitor truncation (MTU/NAT) on the network path
When it happens
Trigger: ReadFrom receives a UDP datagram whose payload length is less than the AES-GCM nonce size after the packet is routed to decrypt — i.e. a truncated, empty, or non-encrypted packet.
Common situations: Random internet UDP noise/scanning hitting the QUIC port, an MTU/truncation issue, or a peer not using the expected encryption.
Related errors
- accpet on closed listener
- kcp: wrong connection type
- accpet on closed listener
- UDP redirect is not available on the Windows platform
- not a packet connection
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/10067f3c83160f71.
Report an issue: GitHub.