diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MsgPackLogExporterThreadSafetyTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MsgPackLogExporterThreadSafetyTests.cs
new file mode 100644
index 0000000000..92433bad1b
--- /dev/null
+++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MsgPackLogExporterThreadSafetyTests.cs
@@ -0,0 +1,193 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable disable
+
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Microsoft.Extensions.Logging;
+using OpenTelemetry.Exporter.Geneva.MsgPack;
+using OpenTelemetry.Logs;
+using OpenTelemetry.Resources;
+using Xunit;
+
+namespace OpenTelemetry.Exporter.Geneva.Tests;
+
+#pragma warning disable CA1873 // Avoid potentially expensive logging
+
+///
+/// This test suite runs various multi-threaded tests to test for potential race conditions
+/// associated with multi-threaded execution of the log exporter.
+///
+public class MsgPackLogExporterThreadSafetyTests
+{
+ [Fact]
+ public void SerializeLogRecord_ConcurrentThreads_ProducesValidMsgPack()
+ {
+ var exporterOptions = new GenevaExporterOptions();
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ exporterOptions.ConnectionString = "EtwSession=OpenTelemetry";
+ }
+ else
+ {
+ var path = GetRandomFilePath();
+ exporterOptions.ConnectionString = "Endpoint=unix:" + path;
+ }
+
+ // Provide resource attributes including service.name and service.instanceId
+ // These get auto-mapped to cloud.role / cloud.roleInstance.
+ var resourceAttributes = new Dictionary
+ {
+ { "service.name", "TestService" },
+ { "service.instanceId", "Instance123" },
+ };
+ var resource = new Resource(resourceAttributes);
+
+ using var exporter = new MsgPackLogExporter(exporterOptions, () => resource);
+
+ const int threadCount = 8;
+ const int iterationsPerThread = 50;
+ var barrier = new Barrier(threadCount);
+ Exception exception = null;
+
+ // Create a real activity to serialize
+ var sourceName = GetTestMethodName();
+
+ var threads = new Thread[threadCount];
+ for (int t = 0; t < threadCount; t++)
+ {
+ var threadIndex = t;
+ threads[t] = new Thread(() =>
+ {
+ try
+ {
+ // Wait for all threads to be ready, maximizing contention on CreateFraming
+ barrier.SignalAndWait();
+
+ for (int i = 0; i < iterationsPerThread; i++)
+ {
+ List logRecords = [];
+ using var loggerFactory = LoggerFactory.Create(builder => builder
+ .AddOpenTelemetry(options =>
+ {
+ options.AddInMemoryExporter(logRecords);
+ }));
+
+ var logger = loggerFactory.CreateLogger();
+
+ logger.LogInformation("Hello from {Thread} {Iteration}.", threadIndex, i);
+
+ Assert.Single(logRecords);
+
+ var serialized = exporter.SerializeLogRecord(logRecords[0]);
+
+ // Validate: the serialized data must be valid MessagePack
+ // representing a proper Fluentd Forward Mode message.
+ try
+ {
+ var data = new byte[serialized.Count];
+ Array.Copy(serialized.Array!, serialized.Offset, data, 0, serialized.Count);
+
+ var msgPackReader = new MessagePack.MessagePackReader(data);
+
+ var deserialized = MessagePack.MessagePackSerializer.Deserialize