diff --git a/NEWS b/NEWS
index 2a6c5c43942f2c5fade9c5610da3d23c3ae067bb..658ca8c5fd32712199345b869996bece21f24f67 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ ver 0.19.2 (not yet released)
   - ffmpeg: recognize MIME type audio/aacp
 * output
   - fix memory leak after filter initialization error
+  - fall back to PCM if given DSD sample rate is not supported
 * fix assertion failure on unsupported PCM conversion
 * auto-disable plugins that require GLib when --disable-glib is used
 
diff --git a/src/output/OutputThread.cxx b/src/output/OutputThread.cxx
index 54664bb651f9bd9271dc7609b8dbd4927a342c1e..2ec0670c10079694aa8d8de315f73d0514178dfd 100644
--- a/src/output/OutputThread.cxx
+++ b/src/output/OutputThread.cxx
@@ -22,6 +22,7 @@
 #include "OutputAPI.hxx"
 #include "Domain.hxx"
 #include "pcm/PcmMix.hxx"
+#include "pcm/Domain.hxx"
 #include "notify.hxx"
 #include "filter/FilterInternal.hxx"
 #include "filter/plugins/ConvertFilterPlugin.hxx"
@@ -165,6 +166,10 @@ AudioOutput::Open()
 	out_audio_format.ApplyMask(config_audio_format);
 
 	mutex.unlock();
+
+	const AudioFormat retry_audio_format = out_audio_format;
+
+ retry_without_dsd:
 	success = ao_plugin_open(this, out_audio_format, error);
 	mutex.lock();
 
@@ -189,6 +194,31 @@ AudioOutput::Open()
 
 		mutex.unlock();
 		ao_plugin_close(this);
+
+		if (error.IsDomain(pcm_domain) &&
+		    out_audio_format.format == SampleFormat::DSD) {
+			/* if the audio output supports DSD, but not
+			   the given sample rate, it asks MPD to
+			   resample; resampling DSD however is not
+			   implemented; our last resort is to give up
+			   DSD and fall back to PCM */
+
+			// TODO: clean up this workaround
+
+			FormatError(output_domain, "Retrying without DSD");
+
+			out_audio_format = retry_audio_format;
+			out_audio_format.format = SampleFormat::FLOAT;
+
+			/* clear the Error to allow reusing it */
+			error.Clear();
+
+			/* sorry for the "goto" - this is a workaround
+			   for the stable branch that should be as
+			   unintrusive as possible */
+			goto retry_without_dsd;
+		}
+
 		CloseFilter();
 		mutex.lock();