diff --git a/test/unit/io/sam_file/format_bam_test.cpp b/test/unit/io/sam_file/format_bam_test.cpp
index e3d436efe3..2d2e731a9c 100644
--- a/test/unit/io/sam_file/format_bam_test.cpp
+++ b/test/unit/io/sam_file/format_bam_test.cpp
@@ -393,6 +393,32 @@ struct sam_file_read<seqan3::format_bam> : public sam_file_data
         '\x14', '\x00', '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x12', '\x00', '\x00', '\x00', '\x10', '\x00',
         '\x00', '\x00', '\x11', '\x00', '\x00', '\x00', '\x12', '\x48', '\x00', '\x02', '\x02', '\x03', '\x62', '\x48',
         '\x48', '\x31', '\x41', '\x45', '\x33', '\x30', '\x00'};
+
+    std::vector<std::string> issue3299_output{
+        {'\x42', '\x41', '\x4d', '\x01', '\x35', '\x00', '\x00', '\x00', '\x40', '\x48', '\x44', '\x09', '\x56', '\x4e',
+         '\x3a', '\x31', '\x2e', '\x36', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x68', '\x65',
+         '\x6c', '\x6c', '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x31', '\x30', '\x30', '\x30', '\x0a', '\x40', '\x53',
+         '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x77', '\x6f', '\x72', '\x6c', '\x64', '\x09', '\x4c', '\x4e', '\x3a',
+         '\x32', '\x30', '\x30', '\x30', '\x0a', '\x02', '\x00', '\x00', '\x00', '\x06', '\x00', '\x00', '\x00', '\x68',
+         '\x65', '\x6c', '\x6c', '\x6f', '\x00', '\xe8', '\x03', '\x00', '\x00', '\x06', '\x00', '\x00', '\x00', '\x77',
+         '\x6f', '\x72', '\x6c', '\x64', '\x00', '\xd0', '\x07', '\x00', '\x00'},
+        {'\x42', '\x41', '\x4d', '\x01', '\x3b', '\x00', '\x00', '\x00', '\x40', '\x48', '\x44', '\x09', '\x56', '\x4e',
+         '\x3a', '\x31', '\x2e', '\x36', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x68', '\x65',
+         '\x6c', '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x31', '\x30', '\x30', '\x31',
+         '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x77', '\x6f', '\x72', '\x6c', '\x64', '\x66',
+         '\x6f', '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x32', '\x30', '\x30', '\x31', '\x0a', '\x02', '\x00', '\x00',
+         '\x00', '\x09', '\x00', '\x00', '\x00', '\x68', '\x65', '\x6c', '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x00',
+         '\xe9', '\x03', '\x00', '\x00', '\x09', '\x00', '\x00', '\x00', '\x77', '\x6f', '\x72', '\x6c', '\x64', '\x66',
+         '\x6f', '\x6f', '\x00', '\xd1', '\x07', '\x00', '\x00'},
+        {'\x42', '\x41', '\x4d', '\x01', '\x41', '\x00', '\x00', '\x00', '\x40', '\x48', '\x44', '\x09', '\x56',
+         '\x4e', '\x3a', '\x31', '\x2e', '\x36', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a',
+         '\x68', '\x65', '\x6c', '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', '\x09', '\x4c',
+         '\x4e', '\x3a', '\x31', '\x30', '\x30', '\x32', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e',
+         '\x3a', '\x77', '\x6f', '\x72', '\x6c', '\x64', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', '\x09',
+         '\x4c', '\x4e', '\x3a', '\x32', '\x30', '\x30', '\x32', '\x0a', '\x02', '\x00', '\x00', '\x00', '\x0c',
+         '\x00', '\x00', '\x00', '\x68', '\x65', '\x6c', '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x66', '\x6f',
+         '\x6f', '\x00', '\xea', '\x03', '\x00', '\x00', '\x0c', '\x00', '\x00', '\x00', '\x77', '\x6f', '\x72',
+         '\x6c', '\x64', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', '\x00', '\xd2', '\x07', '\x00', '\x00'}};
 };
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/test/unit/io/sam_file/format_sam_test.cpp b/test/unit/io/sam_file/format_sam_test.cpp
index f69cca440e..0c39c904fe 100644
--- a/test/unit/io/sam_file/format_sam_test.cpp
+++ b/test/unit/io/sam_file/format_sam_test.cpp
@@ -107,6 +107,20 @@ read1	41	*	1	61	1S1M1D1M1I	*	0	0	ACGT	!##$
     std::string wrong_hexadecimal_tag{
         R"(@SQ	SN:ref	LN:150
 read1	41	ref	1	61	1S1M1D1M1I	=	10	300	ACGT	!##$	bH:H:1AE30
+)"};
+
+    std::vector<std::string> issue3299_output{
+        R"(@HD	VN:1.6
+@SQ	SN:hello	LN:1000
+@SQ	SN:world	LN:2000
+)",
+        R"(@HD	VN:1.6
+@SQ	SN:hellofoo	LN:1001
+@SQ	SN:worldfoo	LN:2001
+)",
+        R"(@HD	VN:1.6
+@SQ	SN:hellofoofoo	LN:1002
+@SQ	SN:worldfoofoo	LN:2002
 )"};
 };
 
@@ -384,9 +398,9 @@ TEST_F(sam_format, write_different_header)
 
     write_header();
     ostream.flush();
-    EXPECT_EQ(
-        ostream.str(),
-        "@HD\tVN:1.6\tSO:coordinate\tSS:query\tGO:reference\n@SQ\tSN:ref\tLN:34\n*\t0\tref\t1\t0\t*\t*\t0\t0\t*\t*\n");
+    EXPECT_EQ(ostream.str(),
+              "@HD\tVN:1.6\tSO:coordinate\tSS:query\tGO:reference\n@SQ\tSN:ref\tLN:34\n*\t0\tref\t1\t0\t*\t*"
+              "\t0\t0\t*\t*\n");
 }
 
 TEST_F(sam_format, issue2195)
diff --git a/test/unit/io/sam_file/sam_file_format_test_template.hpp b/test/unit/io/sam_file/sam_file_format_test_template.hpp
index 6f9b3bc01a..6018b1fda1 100644
--- a/test/unit/io/sam_file/sam_file_format_test_template.hpp
+++ b/test/unit/io/sam_file/sam_file_format_test_template.hpp
@@ -705,6 +705,58 @@ TYPED_TEST_P(sam_file_write, format_errors)
                  seqan3::format_error);
 }
 
+TYPED_TEST_P(sam_file_write, issue3299)
+{
+    using sam_file_output_t = seqan3::sam_file_output<typename seqan3::sam_file_output<>::selected_field_ids,
+                                                      seqan3::type_list<TypeParam>,
+                                                      std::vector<std::string>>;
+    std::vector<std::string> seq_names{"hello", "world"};
+    std::vector<size_t> seq_lengths{1000, 2000};
+
+    // Issue: Moved-from sam_file_output would try to write header on destruction
+    {
+        sam_file_output_t fout1{std::ostringstream{}, seq_names, seq_lengths, TypeParam{}};
+        sam_file_output_t fout2{std::move(fout1)};
+    }
+
+    // Issue: Header does not own ref_ids: ref_ids outlives sam_file_output
+    {
+        std::vector<sam_file_output_t> alignment_streams;
+        auto seq_names_copy = seq_names;
+        alignment_streams.emplace_back(std::ostringstream{}, seq_names_copy, seq_lengths, TypeParam{});
+        // Destructor calls:
+        // 1) seq_names_copy
+        // 2) alignment_streams, starting with the one element it holds
+    }
+
+    // Issue: Header does not own ref_ids: ref_ids may change
+    size_t const iterations{this->issue3299_output.size()};
+    // Order of destruction of vector elements differs between GCC and Clang
+    std::vector<std::ostringstream> outputs(iterations);
+    {
+        std::vector<sam_file_output_t> alignment_streams;
+        for (size_t i = 0; i < iterations; ++i)
+        {
+            alignment_streams.emplace_back(outputs[i], seq_names, seq_lengths, TypeParam{});
+
+            std::ranges::for_each(seq_names,
+                                  [](std::string & str)
+                                  {
+                                      str += "foo";
+                                  });
+            std::ranges::for_each(seq_lengths,
+                                  [](size_t & len)
+                                  {
+                                      ++len;
+                                  });
+        }
+    }
+    for (size_t i = 0; i < iterations; ++i)
+    {
+        EXPECT_EQ(outputs[i].str(), this->issue3299_output[i]) << "Iteration: " << i;
+    }
+}
+
 REGISTER_TYPED_TEST_SUITE_P(sam_file_read,
                             input_concept,
                             header_sucess,
@@ -729,4 +781,5 @@ REGISTER_TYPED_TEST_SUITE_P(sam_file_write,
                             with_header,
                             cigar_vector,
                             special_cases,
-                            format_errors);
+                            format_errors,
+                            issue3299);