diff --git a/NEWS b/NEWS
index ed5b4d94c..1f40838f0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 ver 0.21.12 (not yet released)
 * decoder
   - mad: update bit rate after seeking
+  - mad: fix several bugs preventing the plugin from decoding the last frame
   - opus: ignore case in replay gain tag names
   - opus, vorbis: decode the "end of stream" packet
 * output
diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx
index 626fec855..c27103185 100644
--- a/src/decoder/plugins/MadDecoderPlugin.cxx
+++ b/src/decoder/plugins/MadDecoderPlugin.cxx
@@ -749,9 +749,17 @@ MadDecoder::DecodeFirstFrame(Tag *tag) noexcept
 		struct lame lame;
 		if (parse_lame(&lame, &ptr, &bitlen)) {
 			if (gapless_playback && input_stream.IsSeekable()) {
+				/* libmad inserts 529 samples of
+				   silence at the beginning and
+				   removes those 529 samples at the
+				   end */
 				drop_start_samples = lame.encoder_delay +
 				                           DECODERDELAY;
 				drop_end_samples = lame.encoder_padding;
+				if (drop_end_samples > DECODERDELAY)
+					drop_end_samples -= DECODERDELAY;
+				else
+					drop_end_samples = 0;
 			}
 
 			/* Album gain isn't currently used.  See comment in