RocketChat/Rocket.Chat · warning

Failed to start audio playback:

Error message

Failed to start audio playback:

What it means

Client-side: the media player assigned a new track to an <audio> element (src + load()) and called play(); the returned promise rejected. Browsers reject play() with NotAllowedError when autoplay is blocked (no prior user gesture), NotSupportedError when the source cannot be decoded, or AbortError when a new load interrupts the play request. The warn is console-only and the player simply stays paused.

Source

Thrown at apps/meteor/client/providers/MediaPlayerProvider/MediaPlayerProvider.tsx:56

	}, []);
	const setAudioRef = useMergedRefs(audioCallback, mediaRef);

	const play = useStableCallback((next: PersistentAudioTrack) => {
		const audio = audioRef.current;
		if (!audio) {
			return;
		}

		if (trackRef.current?.id !== next.id) {
			setTrack(next);
			setCurrentTime(0);
			setDuration(0);
			audio.src = next.url;
			audio.load();
		}

		audio.playbackRate = playbackRate;
		audio.play().catch((err) => console.warn('Failed to start audio playback:', err));
	});

	const toggle = useStableCallback(() => {
		const audio = audioRef.current;
		if (!audio || !trackRef.current) {
			return;
		}
		if (audio.paused) {
			audio.play().catch((err) => console.warn('Failed to resume audio playback:', err));
		} else {
			audio.pause();
		}
	});

	const seek = useStableCallback((time: number) => {
		const audio = audioRef.current;
		if (!audio) {
			return;

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Start playback from a user gesture (the play/toggle button); programmatic starts are the ones autoplay policy blocks
  2. Check the network tab: the audio request must return 200 with a proper audio content-type
  3. Refresh expired file URLs before assigning audio.src
  4. Serve widely supported codecs and handle NotAllowedError by showing a paused player the user can click
Defensive patterns

Strategy: try-catch

Type guard

function isAutoplayBlocked(err: unknown): err is DOMException {
	return err instanceof DOMException && err.name === 'NotAllowedError';
}

Try / catch

audio.play().catch((err: unknown) => {
	if (err instanceof DOMException && err.name === 'NotAllowedError') {
		setPausedState(); // show a play button for the user to click
		return;
	}
	console.warn('Failed to start audio playback:', err);
});

Prevention

When it happens

Trigger: Playback started programmatically (effect on track change) without a qualifying user interaction; audio URL 404/403 (expired file-upload auth links); unsupported codec or wrong content-type from the server; rapid track switches aborting the previous play() call.

Common situations: Chrome/Safari autoplay policies on fresh tabs or direct deep-links; long-lived sessions where file URLs expire; proxies stripping Accept-Ranges or content-type on audio responses.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/1dbb488d08d36e7f. Report an issue: GitHub.