AlexxIT/go2rtc · error
%w: %v
Error message
%w: %v
What it means
When the AEAD Open (authenticated decryption) fails — typically because the Poly1305 tag does not verify — Decrypt wraps the underlying error as '<errDecryptPacket>: <detail>'. This means the record failed authentication: wrong key material, wrong nonce, or corrupted/altered ciphertext.
Solutions
- Check PSK/session key agreement — both sides must derive identical keys (verify credentials/handshake).
- Ensure records are processed in order and sequence numbers/epochs match; drop replays before decrypt.
- Enable DTLS retransmission/anti-replay handling on the transport and retransmit lost handshake flights.
- If corruption is environmental (bad Wi-Fi/cabling), fix the link layer or add per-record retransmission.
Example fix
// before
out, err := cipher.Decrypt(h, raw)
if err != nil { return err }
// after
out, err := cipher.Decrypt(h, raw)
if err != nil {
log.Printf("dtls decrypt failed (seq=%d): %v", h.SequenceNumber, err)
return nil // drop inauthentic record, don't crash session
} Defensive patterns
Strategy: try-catch
Validate before calling
// Drop replays and out-of-order records before decrypting
if h.SequenceNumber <= lastSeenSeq || h.Epoch != expectedEpoch {
return nil
} Try / catch
out, err := cipher.Decrypt(h, raw)
if err != nil {
if errors.Is(err, errDecryptPacket) {
log.Printf("inauthentic record seq=%d: %v", h.SequenceNumber, err)
return nil // drop record, keep session
}
return err
} Prevention
- Verify PSK/credentials match on both peers
- Process records in order and enforce anti-replay windows
- Retransmit lost handshake flights to avoid key desync
- Fix physical link issues if corruption rates are high
When it happens
Trigger: Calling Decrypt when remoteCipher.Open returns an error: packet bytes corrupted in transit, replayed/reordered records producing wrong epoch/sequence nonce, or DTLS keys not synchronized (peer rekeyed mid-session).
Common situations: UDP packet corruption or tampering; handshake completed with mismatched keys (e.g. PSK differs between peers); sequence-number desync after dropped/reordered datagrams; replay of old packets.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/c571013601fa20c8.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/tutk/dtls/cipher.go:116
func (c *ChaCha20Poly1305Cipher) Decrypt(header recordlayer.Header, in []byte) ([]byte, error) {
err := header.Unmarshal(in)
switch {
case err != nil:
return nil, err
case header.ContentType == protocol.ContentTypeChangeCipherSpec:
return in, nil
case len(in) <= header.Size()+chachaTagLength:
return nil, fmt.Errorf("ciphertext too short: %d <= %d", len(in), header.Size()+chachaTagLength)
}
nonce := computeNonce(c.remoteWriteIV, header.Epoch, header.SequenceNumber)
out := in[header.Size():]
additionalData := generateAEADAdditionalData(&header, len(out)-chachaTagLength)
out, err = c.remoteCipher.Open(out[:0], nonce, out, additionalData)
if err != nil {
return nil, fmt.Errorf("%w: %v", errDecryptPacket, err)
}
return append(in[:header.Size()], out...), nil
}
type TLSEcdhePskWithChacha20Poly1305Sha256 struct {
aead atomic.Value
}
func NewTLSEcdhePskWithChacha20Poly1305Sha256() *TLSEcdhePskWithChacha20Poly1305Sha256 {
return &TLSEcdhePskWithChacha20Poly1305Sha256{}
}
func (c *TLSEcdhePskWithChacha20Poly1305Sha256) CertificateType() clientcertificate.Type {
return clientcertificate.Type(0)
}
func (c *TLSEcdhePskWithChacha20Poly1305Sha256) KeyExchangeAlgorithm() dtls.CipherSuiteKeyExchangeAlgorithm {View on GitHub (pinned to c245815e75)