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

  1. Update @discordjs/voice to the latest version so the new encryption mode is supported for receiving.
  2. Ensure the installed crypto packages (sodium / libsodium-wrappers / @stablelib/xchacha20poly1305 / @noble/ciphers) match the mode requirements of the current version.
  3. Log mode (this.mode / negotiated mode) to confirm which unsupported value triggered the throw.
  4. 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

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


AI-assisted analysis of discordjs/discord.js@a81ed8a306 (2026-08-30). Data as JSON: /api/errors/3bfd437ec1c57b8f. Report an issue: GitHub.