diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3733d9728..95ff44c6e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 ### Features
 
+- When running on Android, the SDK now links errors and events originating on different layers (managed, native errors) via `trace ID` ([#1997](https://github.com/getsentry/sentry-unity/pull/1997))
 - The SDK now reports the game's name as part of the app context ([2083](https://github.com/getsentry/sentry-unity/pull/2083))
 - The SDK now reports the active scene's name as part of the `Unity Context` ([2084](https://github.com/getsentry/sentry-unity/pull/2084))
 
diff --git a/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs b/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs
index ef54bb937..0f80acfd8 100644
--- a/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs
+++ b/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs
@@ -1,3 +1,4 @@
+using System;
 using UnityEngine;
 
 namespace Sentry.Unity.Android;
@@ -15,7 +16,8 @@ public AndroidJavaScopeObserver(SentryOptions options, IJniExecutor jniExecutor)
         _jniExecutor = jniExecutor;
     }
 
-    private AndroidJavaObject GetSentryJava() => new AndroidJavaClass("io.sentry.Sentry");
+    private static AndroidJavaObject GetSentryJava() => new AndroidJavaClass("io.sentry.Sentry");
+    private static AndroidJavaObject GetInternalSentryJava() => new AndroidJavaClass("io.sentry.android.core.InternalSentrySdk");
 
     public override void AddBreadcrumbImpl(Breadcrumb breadcrumb)
     {
@@ -88,4 +90,14 @@ public override void UnsetUserImpl()
             sentry.CallStatic("setUser", null);
         });
     }
+
+    public override void SetTraceImpl(SentryId traceId, SpanId spanId)
+    {
+        _jniExecutor.Run(() =>
+        {
+            using var sentry = GetInternalSentryJava();
+            // We have to explicitly cast to `(Double?)`
+            sentry.CallStatic("setTrace", traceId.ToString(), spanId.ToString(), (Double?)null, (Double?)null);
+        });
+    }
 }
diff --git a/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs b/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs
index c61de02b9..fc63611d7 100644
--- a/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs
+++ b/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs
@@ -206,6 +206,7 @@ internal void ModifyManifest(string basePath)
         // Disabling the native in favor of the C# layer for now
         androidManifest.SetNdkEnabled(_options.NdkIntegrationEnabled);
         androidManifest.SetNdkScopeSync(_options.NdkScopeSyncEnabled);
+        androidManifest.SetAutoTraceIdGeneration(false);
         androidManifest.SetAutoSessionTracking(false);
         androidManifest.SetAutoAppLifecycleBreadcrumbs(false);
         androidManifest.SetAnr(false);
@@ -483,6 +484,9 @@ internal void SetNdkEnabled(bool enableNdk)
     internal void SetNdkScopeSync(bool enableNdkScopeSync)
         => SetMetaData($"{SentryPrefix}.ndk.scope-sync.enable", enableNdkScopeSync.ToString());
 
+    internal void SetAutoTraceIdGeneration(bool enableAutoTraceIdGeneration)
+        => SetMetaData($"{SentryPrefix}.traces.enable-auto-id-generation", enableAutoTraceIdGeneration.ToString());
+
     internal void SetDebug(bool debug) => SetMetaData($"{SentryPrefix}.debug", debug ? "true" : "false");
 
     // https://github.com/getsentry/sentry-java/blob/db4dfc92f202b1cefc48d019fdabe24d487db923/sentry/src/main/java/io/sentry/SentryLevel.java#L4-L9
diff --git a/src/Sentry.Unity.Native/NativeScopeObserver.cs b/src/Sentry.Unity.Native/NativeScopeObserver.cs
index 5075febca..3499e38d8 100644
--- a/src/Sentry.Unity.Native/NativeScopeObserver.cs
+++ b/src/Sentry.Unity.Native/NativeScopeObserver.cs
@@ -40,6 +40,10 @@ public override void SetUserImpl(SentryUser user)
     }
 
     public override void UnsetUserImpl() => C.sentry_remove_user();
+    public override void SetTraceImpl(SentryId traceId, SpanId spanId)
+    {
+        // TODO: Needs to be implemented
+    }
 
     private static string GetTimestamp(DateTimeOffset timestamp) =>
         // "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.
diff --git a/src/Sentry.Unity.iOS/NativeScopeObserver.cs b/src/Sentry.Unity.iOS/NativeScopeObserver.cs
index f46d69bdf..836a8532e 100644
--- a/src/Sentry.Unity.iOS/NativeScopeObserver.cs
+++ b/src/Sentry.Unity.iOS/NativeScopeObserver.cs
@@ -25,6 +25,10 @@ public override void SetUserImpl(SentryUser user) =>
         SentryCocoaBridgeProxy.SetUser(user.Email, user.Id, user.IpAddress, user.Username);
 
     public override void UnsetUserImpl() => SentryCocoaBridgeProxy.UnsetUser();
+    public override void SetTraceImpl(SentryId traceId, SpanId spanId)
+    {
+        // TODO: Needs to be implemented
+    }
 
     internal static string GetTimestamp(DateTimeOffset timestamp) =>
         // "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.
diff --git a/src/Sentry.Unity/ScopeObserver.cs b/src/Sentry.Unity/ScopeObserver.cs
index 86dc3e872..9055ff55e 100644
--- a/src/Sentry.Unity/ScopeObserver.cs
+++ b/src/Sentry.Unity/ScopeObserver.cs
@@ -3,7 +3,7 @@
 namespace Sentry.Unity;
 
 /// <summary>
-/// Sentry Unity Scope Observer wrapper for the common behaviour accross platforms.
+/// Sentry Unity Scope Observer wrapper for the common behaviour across platforms.
 /// </summary>
 public abstract class ScopeObserver : IScopeObserver
 {
@@ -81,10 +81,17 @@ public void SetUser(SentryUser? user)
         }
     }
 
-    public void SetTrace(SentryId traceId, SpanId parentSpanId)
-    { }
-
     public abstract void SetUserImpl(SentryUser user);
 
     public abstract void UnsetUserImpl();
+
+    public void SetTrace(SentryId traceId, SpanId spanId)
+    {
+        _options.DiagnosticLogger?.Log(
+            SentryLevel.Debug, "{0} Scope Sync - Setting Trace traceId:{1} spanId:{2}", null,
+                _name, traceId, spanId);
+        SetTraceImpl(traceId, spanId);
+    }
+
+    public abstract void SetTraceImpl(SentryId traceId, SpanId spanId);
 }
diff --git a/src/Sentry.Unity/SentryUnitySDK.cs b/src/Sentry.Unity/SentryUnitySDK.cs
index 029e34194..c32ae428d 100644
--- a/src/Sentry.Unity/SentryUnitySDK.cs
+++ b/src/Sentry.Unity/SentryUnitySDK.cs
@@ -51,6 +51,11 @@ private SentryUnitySdk(SentryUnityOptions options)
 
         unitySdk._dotnetSdk = SentrySdk.Init(options);
 
+        // For now, we're creating a new trace after initializing to be able to tie errors and crashes together on all
+        // layers. To be able to regenerate new traces based on some mechanism, this will move into some sort of
+        // integration i.e. scene manager.
+        SentrySdk.SetTrace(SentryId.Create(), SpanId.Create());
+
         if (options.NativeContextWriter is { } contextWriter)
         {
             SentrySdk.ConfigureScope((scope) =>
diff --git a/test/Sentry.Unity.Android.Tests/TestSentryJava.cs b/test/Sentry.Unity.Android.Tests/TestSentryJava.cs
index 16cb0fd97..be1139782 100644
--- a/test/Sentry.Unity.Android.Tests/TestSentryJava.cs
+++ b/test/Sentry.Unity.Android.Tests/TestSentryJava.cs
@@ -19,6 +19,7 @@ public void Init(IJniExecutor jniExecutor, SentryUnityOptions options, TimeSpan
     public bool? CrashedLastRun(IJniExecutor jniExecutor) => IsCrashedLastRun;
 
     public void Close(IJniExecutor jniExecutor) { }
+    public void SetTrace(IJniExecutor jniExecutor, string traceId, string spanId) { }
 
     public void WriteScope(
         IJniExecutor jniExecutor,