diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx
index 4251d8237..0d4e7c61e 100644
--- a/src/output/MultipleOutputs.cxx
+++ b/src/output/MultipleOutputs.cxx
@@ -58,14 +58,8 @@ try {
 	AudioOutput *output = audio_output_new(event_loop, block,
 					       mixer_listener,
 					       pc, error);
-	if (output == nullptr) {
-		if (block.line > 0)
-			FormatFatalError("line %i: %s",
-					 block.line,
-					 error.GetMessage());
-		else
-			FatalError(error);
-	}
+	if (output == nullptr)
+		throw std::runtime_error(error.GetMessage());
 
 	return output;
 } catch (const std::runtime_error &e) {
@@ -192,32 +186,27 @@ MultipleOutputs::SetReplayGainMode(ReplayGainMode mode)
 		ao->SetReplayGainMode(mode);
 }
 
-bool
-MultipleOutputs::Play(MusicChunk *chunk, Error &error)
+void
+MultipleOutputs::Play(MusicChunk *chunk)
 {
 	assert(buffer != nullptr);
 	assert(pipe != nullptr);
 	assert(chunk != nullptr);
 	assert(chunk->CheckFormat(input_audio_format));
 
-	if (!Update()) {
+	if (!Update())
 		/* TODO: obtain real error */
-		error.Set(output_domain, "Failed to open audio output");
-		return false;
-	}
+		throw std::runtime_error("Failed to open audio output");
 
 	pipe->Push(chunk);
 
 	for (auto ao : outputs)
 		ao->LockPlay();
-
-	return true;
 }
 
-bool
+void
 MultipleOutputs::Open(const AudioFormat audio_format,
-		      MusicBuffer &_buffer,
-		      Error &error)
+		      MusicBuffer &_buffer)
 {
 	bool ret = false, enabled = false;
 
@@ -251,17 +240,16 @@ MultipleOutputs::Open(const AudioFormat audio_format,
 			ret = true;
 	}
 
-	if (!enabled)
-		error.Set(output_domain, "All audio outputs are disabled");
-	else if (!ret)
-		/* TODO: obtain real error */
-		error.Set(output_domain, "Failed to open audio output");
-
-	if (!ret)
+	if (!enabled) {
 		/* close all devices if there was an error */
 		Close();
-
-	return ret;
+		throw std::runtime_error("All audio outputs are disabled");
+	} else if (!ret) {
+		/* close all devices if there was an error */
+		Close();
+		/* TODO: obtain real error */
+		throw std::runtime_error("Failed to open audio output");
+	}
 }
 
 /**
diff --git a/src/output/MultipleOutputs.hxx b/src/output/MultipleOutputs.hxx
index b0d838a5b..538c86e1b 100644
--- a/src/output/MultipleOutputs.hxx
+++ b/src/output/MultipleOutputs.hxx
@@ -118,13 +118,13 @@ public:
 	/**
 	 * Opens all audio outputs which are not disabled.
 	 *
+	 * Throws #std::runtime_error on error.
+	 *
 	 * @param audio_format the preferred audio format
 	 * @param _buffer the #music_buffer where consumed #MusicChunk objects
 	 * should be returned
-	 * @return true on success, false on failure
 	 */
-	bool Open(const AudioFormat audio_format, MusicBuffer &_buffer,
-		  Error &error);
+	void Open(const AudioFormat audio_format, MusicBuffer &_buffer);
 
 	/**
 	 * Closes all audio outputs.
@@ -143,11 +143,11 @@ public:
 	 * Enqueue a #MusicChunk object for playing, i.e. pushes it to a
 	 * #MusicPipe.
 	 *
+	 * Throws #std::runtime_error on error (all closed then).
+	 *
 	 * @param chunk the #MusicChunk object to be played
-	 * @return true on success, false if no audio output was able to play
-	 * (all closed then)
 	 */
-	bool Play(MusicChunk *chunk, Error &error);
+	void Play(MusicChunk *chunk);
 
 	/**
 	 * Checks if the output devices have drained their music pipe, and
diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx
index 9acc091a3..42f3d8d4e 100644
--- a/src/player/Thread.cxx
+++ b/src/player/Thread.cxx
@@ -37,6 +37,8 @@
 #include "thread/Name.hxx"
 #include "Log.hxx"
 
+#include <stdexcept>
+
 #include <string.h>
 
 static constexpr Domain player_domain("player");
@@ -443,20 +445,10 @@ Player::OpenOutput()
 	assert(pc.state == PlayerState::PLAY ||
 	       pc.state == PlayerState::PAUSE);
 
-	Error error;
-	if (pc.outputs.Open(play_audio_format, buffer, error)) {
-		output_open = true;
-		paused = false;
-
-		pc.Lock();
-		pc.state = PlayerState::PLAY;
-		pc.Unlock();
-
-		idle_add(IDLE_PLAYER);
-
-		return true;
-	} else {
-		LogError(error);
+	try {
+		pc.outputs.Open(play_audio_format, buffer);
+	} catch (const std::runtime_error &e) {
+		LogError(e);
 
 		output_open = false;
 
@@ -465,7 +457,7 @@ Player::OpenOutput()
 		paused = true;
 
 		pc.Lock();
-		pc.SetError(PlayerError::OUTPUT, std::move(error));
+		pc.SetError(PlayerError::OUTPUT, std::current_exception());
 		pc.state = PlayerState::PAUSE;
 		pc.Unlock();
 
@@ -473,6 +465,17 @@ Player::OpenOutput()
 
 		return false;
 	}
+
+	output_open = true;
+	paused = false;
+
+	pc.Lock();
+	pc.state = PlayerState::PLAY;
+	pc.Unlock();
+
+	idle_add(IDLE_PLAYER);
+
+	return true;
 }
 
 bool
@@ -556,9 +559,10 @@ Player::SendSilence()
 	chunk->length = num_frames * frame_size;
 	PcmSilence({chunk->data, chunk->length}, play_audio_format.format);
 
-	Error error;
-	if (!pc.outputs.Play(chunk, error)) {
-		LogError(error);
+	try {
+		pc.outputs.Play(chunk);
+	} catch (const std::runtime_error &e) {
+		LogError(e);
 		buffer.Return(chunk);
 		return false;
 	}
@@ -770,12 +774,11 @@ update_song_tag(PlayerControl &pc, DetachedSong &song, const Tag &new_tag)
  *
  * Player lock is not held.
  */
-static bool
+static void
 play_chunk(PlayerControl &pc,
 	   DetachedSong &song, MusicChunk *chunk,
 	   MusicBuffer &buffer,
-	   const AudioFormat format,
-	   Error &error)
+	   const AudioFormat format)
 {
 	assert(chunk->CheckFormat(format));
 
@@ -784,7 +787,7 @@ play_chunk(PlayerControl &pc,
 
 	if (chunk->IsEmpty()) {
 		buffer.Return(chunk);
-		return true;
+		return;
 	}
 
 	pc.Lock();
@@ -793,12 +796,9 @@ play_chunk(PlayerControl &pc,
 
 	/* send the chunk to the audio outputs */
 
-	if (!pc.outputs.Play(chunk, error))
-		return false;
-
+	pc.outputs.Play(chunk);
 	pc.total_play_time += (double)chunk->length /
 		format.GetTimeToSize();
-	return true;
 }
 
 inline bool
@@ -899,15 +899,16 @@ Player::PlayNextChunk()
 
 	/* play the current chunk */
 
-	Error error;
-	if (!play_chunk(pc, *song, chunk, buffer, play_audio_format, error)) {
-		LogError(error);
+	try {
+		play_chunk(pc, *song, chunk, buffer, play_audio_format);
+	} catch (const std::runtime_error &e) {
+		LogError(e);
 
 		buffer.Return(chunk);
 
 		pc.Lock();
 
-		pc.SetError(PlayerError::OUTPUT, std::move(error));
+		pc.SetError(PlayerError::OUTPUT, std::current_exception());
 
 		/* pause: the user may resume playback as soon as an
 		   audio output becomes available */