diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx
index a59999bb3..7b850265b 100644
--- a/src/DecoderAPI.cxx
+++ b/src/DecoderAPI.cxx
@@ -134,6 +134,10 @@ gcc_pure
 static DecoderCommand
 decoder_get_virtual_command(Decoder &decoder)
 {
+	if (decoder.error.IsDefined())
+		/* an error has occurred: stop the decoder plugin */
+		return DecoderCommand::STOP;
+
 	const DecoderControl &dc = decoder.dc;
 	assert(dc.pipe != nullptr);
 
diff --git a/src/DecoderInternal.hxx b/src/DecoderInternal.hxx
index e98e0aae3..87c6828d4 100644
--- a/src/DecoderInternal.hxx
+++ b/src/DecoderInternal.hxx
@@ -22,6 +22,7 @@
 
 #include "DecoderCommand.hxx"
 #include "ReplayGainInfo.hxx"
+#include "util/Error.hxx"
 
 class PcmConvert;
 struct DecoderControl;
@@ -87,6 +88,12 @@ struct Decoder {
 	 */
 	unsigned replay_gain_serial;
 
+	/**
+	 * An error has occurred (in DecoderAPI.cxx), and the plugin
+	 * will be asked to stop.
+	 */
+	Error error;
+
 	Decoder(DecoderControl &_dc, bool _initial_seek_pending, Tag *_tag)
 		:dc(_dc),
 		 convert(nullptr),
diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx
index 4d0bc13b5..2df131d19 100644
--- a/src/DecoderThread.cxx
+++ b/src/DecoderThread.cxx
@@ -360,7 +360,12 @@ decoder_run_song(DecoderControl &dc,
 
 	dc.Lock();
 
-	if (ret)
+	if (decoder.error.IsDefined()) {
+		/* copy the Error from sruct Decoder to
+		   DecoderControl */
+		dc.state = DecoderState::ERROR;
+		dc.error = std::move(decoder.error);
+	} else if (ret)
 		dc.state = DecoderState::STOP;
 	else {
 		dc.state = DecoderState::ERROR;