discordjs/discord.js · error · RangeError
Unsupported decryption method: ${mode}
Error message
Unsupported decryption method: ${mode} What it means
VoiceReceiver.decrypt throws this RangeError when the receiver's decryption mode string does not match any branch of its switch. The mode comes from the negotiated encryption mode stored on the receiver, so this means the library instance cannot decrypt with the mode the voice connection selected — typically because the installed version predates that mode. Like error 320, the default branch is expected to be unreachable in a healthy negotiation.
Source
Thrown at packages/voice/src/receive/VoiceReceiver.ts:128
decipheriv.setAuthTag(authTag);
return Buffer.concat([decipheriv.update(encrypted), decipheriv.final()]);
}
case 'aead_xchacha20_poly1305_rtpsize': {
// Combined mode expects authtag in the encrypted message
return Buffer.from(
methods.crypto_aead_xchacha20poly1305_ietf_decrypt(
Buffer.concat([encrypted, authTag]),
header,
nonce,
secretKey,
),
);
}
default: {
throw new RangeError(`Unsupported decryption method: ${mode}`);
}
}
}
/**
* Parses an audio packet, decrypting it to yield an Opus packet.
*
* @param rtp - The incoming RTP packet buffer to be parsed
* @param mode - The encryption mode
* @param nonce - The nonce buffer used by the connection for encryption
* @param secretKey - The secret key used by the connection for encryption
* @param userId - The user id that sent the packet
* @param ssrc - already-parsed SSRC (Synchronization Source Identifier) from the RTP Header
* @returns Decrypted Opus payload and RTP header information, or null if DAVE decrypt failed in a way that should be ignored
*/
private parsePacket(
rtp: Buffer,
mode: string,View on GitHub (pinned to a81ed8a306)
Solutions
- Update @discordjs/voice to the latest version so the new encryption mode is supported for receiving.
- Ensure the installed crypto packages (sodium / libsodium-wrappers / @stablelib/xchacha20poly1305 / @noble/ciphers) match the mode requirements of the current version.
- Log mode (this.mode / negotiated mode) to confirm which unsupported value triggered the throw.
- Restrict gateway modes via library config or rejoin the voice channel to renegotiate a supported mode.
Example fix
// before const audio = receiver.subscribe(userId); // receiver.decrypt throws for new mode on old version // after // npm i @discordjs/voice@latest (handles aead_xchacha20_poly1305_rtpsize) const audio = receiver.subscribe(userId);
Defensive patterns
Strategy: try-catch
Validate before calling
// Before wiring the receiver, verify the negotiated mode is decryptable:
const DECRYPTABLE = ['aead_xchacha20_poly1305_rtpsize', 'xsalsa20_poly1305_lite', 'xsalsa20_poly1305_suffix', 'xsalsa20_poly1305'];
if (!DECRYPTABLE.includes(negotiatedMode)) console.warn('Receiver cannot decrypt with mode', negotiatedMode, '- update @discordjs/voice'); Type guard
function isDecryptableMode(mode: string): boolean {
return ['aead_xchacha20_poly1305_rtpsize', 'xsalsa20_poly1305_lite', 'xsalsa20_poly1305_suffix', 'xsalsa20_poly1305'].includes(mode);
} Try / catch
try {
const ssrc = receiver.ssrcMap.get(userId);
// packet processing
} catch (e) {
if (e instanceof RangeError && e.message.startsWith('Unsupported decryption method')) {
console.error('Mode mismatch:', e.message); // alert / rejoin with supported mode
} else throw e;
} Prevention
- Update @discordjs/voice whenever Discord changes encryption modes.
- Recreate the receiver when the voice connection is renegotiated so mode and key stay in sync.
- Install the crypto packages required by the negotiated mode (xchacha20 for the AEAD mode).
- Log the negotiated mode at startup to detect mismatches early.
When it happens
Trigger: Connecting a VoiceReceiver to a voice connection whose negotiated encryption mode is unknown to the installed @discordjs/voice version (e.g. aead_xchacha20_poly1305_rtpsize on an older libsodium-only build), or passing a bogus mode directly when calling decrypt manually.
Common situations: Outdated @discordjs/voice after Discord rolled out new encryption modes; mismatch between the connection's negotiated mode and the receiver's expectations; custom code invoking decrypt with a hand-crafted mode value.
Related errors
- Unsupported encryption method: ${encryptionMode}
- No compatible encryption modes. Available include: ${options
- Invalid extension provided: ${extension} Must be one of: ${a
- Invalid size provided: ${size} Must be one of: ${ALLOWED_SIZ
- Cannot destroy VoiceConnection - it has already been destroy
AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30).
Data as JSON: /api/errors/3bfd437ec1c57b8f.
Report an issue: GitHub.