diff --git a/src/Http/Headers/src/CacheControlHeaderValue.cs b/src/Http/Headers/src/CacheControlHeaderValue.cs
index e807a82b323c12590a01119d8f853ba208236a54..3aedf5c176806dbf4f749ea7a39dcb4cdc86abf6 100644
--- a/src/Http/Headers/src/CacheControlHeaderValue.cs
+++ b/src/Http/Headers/src/CacheControlHeaderValue.cs
@@ -502,7 +502,7 @@ public class CacheControlHeaderValue
     /// </summary>
     /// <param name="input">The value to parse.</param>
     /// <param name="parsedValue">The parsed value.</param>
-    /// <returns><see langword="true"/> if input is a valid <see cref="SetCookieHeaderValue"/>, otherwise <see langword="false"/>.</returns>
+    /// <returns><see langword="true"/> if input is a valid <see cref="CacheControlHeaderValue"/>, otherwise <see langword="false"/>.</returns>
     public static bool TryParse(StringSegment input, [NotNullWhen(true)] out CacheControlHeaderValue? parsedValue)
     {
         var index = 0;
diff --git a/src/Http/Headers/src/SetCookieHeaderValue.cs b/src/Http/Headers/src/SetCookieHeaderValue.cs
index 34460aa805847795d23e066c1b155367c7da39cd..719e814179e255f25a1ba7fbbc6a3b0d228df8f0 100644
--- a/src/Http/Headers/src/SetCookieHeaderValue.cs
+++ b/src/Http/Headers/src/SetCookieHeaderValue.cs
@@ -41,6 +41,7 @@ public class SetCookieHeaderValue
 
     private StringSegment _name;
     private StringSegment _value;
+    private List<StringSegment>? _extensions;
 
     private SetCookieHeaderValue()
     {
@@ -177,7 +178,10 @@ public class SetCookieHeaderValue
     /// <summary>
     /// Gets a collection of additional values to append to the cookie.
     /// </summary>
-    public IList<StringSegment> Extensions { get; } = new List<StringSegment>();
+    public IList<StringSegment> Extensions
+    {
+        get => _extensions ??= new List<StringSegment>();
+    }
 
     // name="value"; expires=Sun, 06 Nov 1994 08:49:37 GMT; max-age=86400; domain=domain1; path=path1; secure; samesite={strict|lax|none}; httponly
     /// <inheritdoc />
@@ -236,9 +240,12 @@ public class SetCookieHeaderValue
             length += SeparatorToken.Length + HttpOnlyToken.Length;
         }
 
-        foreach (var extension in Extensions)
+        if (_extensions?.Count > 0)
         {
-            length += SeparatorToken.Length + extension.Length;
+            foreach (var extension in _extensions)
+            {
+                length += SeparatorToken.Length + extension.Length;
+            }
         }
 
         return string.Create(length, (this, maxAge, sameSite), (span, tuple) =>
@@ -291,9 +298,12 @@ public class SetCookieHeaderValue
                 AppendSegment(ref span, HttpOnlyToken, null);
             }
 
-            foreach (var extension in Extensions)
+            if (_extensions?.Count > 0)
             {
-                AppendSegment(ref span, extension, null);
+                foreach (var extension in _extensions)
+                {
+                    AppendSegment(ref span, extension, null);
+                }
             }
         });
     }
@@ -373,9 +383,12 @@ public class SetCookieHeaderValue
             AppendSegment(builder, HttpOnlyToken, null);
         }
 
-        foreach (var extension in Extensions)
+        if (_extensions?.Count > 0)
         {
-            AppendSegment(builder, extension, null);
+            foreach (var extension in _extensions)
+            {
+                AppendSegment(builder, extension, null);
+            }
         }
     }
 
@@ -701,7 +714,7 @@ public class SetCookieHeaderValue
             && Secure == other.Secure
             && SameSite == other.SameSite
             && HttpOnly == other.HttpOnly
-            && HeaderUtilities.AreEqualCollections(Extensions, other.Extensions, StringSegmentComparer.OrdinalIgnoreCase);
+            && HeaderUtilities.AreEqualCollections(_extensions, other._extensions, StringSegmentComparer.OrdinalIgnoreCase);
     }
 
     /// <inheritdoc />
@@ -717,9 +730,12 @@ public class SetCookieHeaderValue
             ^ SameSite.GetHashCode()
             ^ HttpOnly.GetHashCode();
 
-        foreach (var extension in Extensions)
+        if (_extensions?.Count > 0)
         {
-            hash ^= extension.GetHashCode();
+            foreach (var extension in _extensions)
+            {
+                hash ^= extension.GetHashCode();
+            }
         }
 
         return hash;
diff --git a/src/Http/Http.Abstractions/src/CookieBuilder.cs b/src/Http/Http.Abstractions/src/CookieBuilder.cs
index e4c1584852876a84fcb31e458b2865a3228326a9..21ce68649c9e1317ae827756072f4e9f1a527308 100644
--- a/src/Http/Http.Abstractions/src/CookieBuilder.cs
+++ b/src/Http/Http.Abstractions/src/CookieBuilder.cs
@@ -11,6 +11,7 @@ namespace Microsoft.AspNetCore.Http;
 public class CookieBuilder
 {
     private string? _name;
+    private List<string>? _extensions;
 
     /// <summary>
     /// The name of the cookie.
@@ -77,6 +78,14 @@ public class CookieBuilder
     /// </summary>
     public virtual bool IsEssential { get; set; }
 
+    /// <summary>
+    /// Gets a collection of additional values to append to the cookie.
+    /// </summary>
+    public IList<string> Extensions
+    {
+        get => _extensions ??= new List<string>();
+    }
+
     /// <summary>
     /// Creates the cookie options from the given <paramref name="context"/>.
     /// </summary>
@@ -97,7 +106,7 @@ public class CookieBuilder
             throw new ArgumentNullException(nameof(context));
         }
 
-        return new CookieOptions
+        var options = new CookieOptions
         {
             Path = Path ?? "/",
             SameSite = SameSite,
@@ -108,5 +117,14 @@ public class CookieBuilder
             Secure = SecurePolicy == CookieSecurePolicy.Always || (SecurePolicy == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
             Expires = Expiration.HasValue ? expiresFrom.Add(Expiration.GetValueOrDefault()) : default(DateTimeOffset?)
         };
+
+        if (_extensions?.Count > 0)
+        {
+            foreach (var extension in _extensions)
+            {
+                options.Extensions.Add(extension);
+            }
+        }
+        return options;
     }
 }
diff --git a/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt b/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
index a7a9ac6b273c83ff8664b39c089c4fd987ada5a4..cf864b4ca5f6170884fbc3359e133359e7aa71f2 100644
--- a/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
@@ -5,6 +5,7 @@ Microsoft.AspNetCore.Builder.EndpointBuilder.ApplicationServices.get -> System.I
 Microsoft.AspNetCore.Builder.EndpointBuilder.ApplicationServices.set -> void
 Microsoft.AspNetCore.Http.AsParametersAttribute
 Microsoft.AspNetCore.Http.AsParametersAttribute.AsParametersAttribute() -> void
+Microsoft.AspNetCore.Http.CookieBuilder.Extensions.get -> System.Collections.Generic.IList<string!>!
 Microsoft.AspNetCore.Http.DefaultRouteHandlerInvocationContext
 Microsoft.AspNetCore.Http.DefaultRouteHandlerInvocationContext.DefaultRouteHandlerInvocationContext(Microsoft.AspNetCore.Http.HttpContext! httpContext, params object![]! arguments) -> void
 Microsoft.AspNetCore.Http.EndpointMetadataCollection.Enumerator.Current.get -> object!
diff --git a/src/Http/Http.Abstractions/test/CookieBuilderTests.cs b/src/Http/Http.Abstractions/test/CookieBuilderTests.cs
index 536830e71e808448bd1364c047ce32b7285c2b3c..ce171a6ec5272707b6bd6108209a56e81c43a4eb 100644
--- a/src/Http/Http.Abstractions/test/CookieBuilderTests.cs
+++ b/src/Http/Http.Abstractions/test/CookieBuilderTests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
 namespace Microsoft.AspNetCore.Http.Abstractions.Tests;
@@ -50,4 +50,26 @@ public class CookieBuilderTests
     {
         Assert.Equal(new CookieOptions().Path, new CookieBuilder().Build(new DefaultHttpContext()).Path);
     }
+
+    [Fact]
+    public void CookieBuilder_Extensions_Added()
+    {
+        var builder = new CookieBuilder();
+        builder.Extensions.Add("simple");
+        builder.Extensions.Add("key=value");
+
+        var options = builder.Build(new DefaultHttpContext());
+        Assert.Equal(2, options.Extensions.Count);
+        Assert.Contains("simple", options.Extensions);
+        Assert.Contains("key=value", options.Extensions);
+
+        var cookie = options.CreateCookieHeader("name", "value");
+        Assert.Equal("name", cookie.Name);
+        Assert.Equal("value", cookie.Value);
+        Assert.Equal(2, cookie.Extensions.Count);
+        Assert.Contains("simple", cookie.Extensions);
+        Assert.Contains("key=value", cookie.Extensions);
+
+        Assert.Equal("name=value; path=/; simple; key=value", cookie.ToString());
+    }
 }
diff --git a/src/Http/Http.Features/src/CookieOptions.cs b/src/Http/Http.Features/src/CookieOptions.cs
index fb5e80f26d92849b1fcd1716bd7505bd7b36c8ab..8314f349ecba0adf2d449136c028818b2389c10b 100644
--- a/src/Http/Http.Features/src/CookieOptions.cs
+++ b/src/Http/Http.Features/src/CookieOptions.cs
@@ -1,6 +1,8 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using Microsoft.Net.Http.Headers;
+
 namespace Microsoft.AspNetCore.Http;
 
 /// <summary>
@@ -8,6 +10,8 @@ namespace Microsoft.AspNetCore.Http;
 /// </summary>
 public class CookieOptions
 {
+    private List<string>? _extensions;
+
     /// <summary>
     /// Creates a default cookie with a path of '/'.
     /// </summary>
@@ -16,6 +20,28 @@ public class CookieOptions
         Path = "/";
     }
 
+    /// <summary>
+    /// Creates a copy of the given <see cref="CookieOptions"/>.
+    /// </summary>
+    public CookieOptions(CookieOptions options)
+    {
+        ArgumentNullException.ThrowIfNull(options);
+
+        Domain = options.Domain;
+        Path = options.Path;
+        Expires = options.Expires;
+        Secure = options.Secure;
+        SameSite = options.SameSite;
+        HttpOnly = options.HttpOnly;
+        MaxAge = options.MaxAge;
+        IsEssential = options.IsEssential;
+
+        if (options._extensions?.Count > 0)
+        {
+            _extensions = new List<string>(options._extensions);
+        }
+    }
+
     /// <summary>
     /// Gets or sets the domain to associate the cookie with.
     /// </summary>
@@ -63,4 +89,39 @@ public class CookieOptions
     /// consent policy checks may be bypassed. The default value is false.
     /// </summary>
     public bool IsEssential { get; set; }
+
+    /// <summary>
+    /// Gets a collection of additional values to append to the cookie.
+    /// </summary>
+    public IList<string> Extensions
+    {
+        get => _extensions ??= new List<string>();
+    }
+
+    /// <summary>
+    /// Creates a <see cref="SetCookieHeaderValue"/> using the current options.
+    /// </summary>
+    public SetCookieHeaderValue CreateCookieHeader(string name, string value)
+    {
+        var cookie = new SetCookieHeaderValue(name, value)
+        {
+            Domain = Domain,
+            Path = Path,
+            Expires = Expires,
+            Secure = Secure,
+            HttpOnly = HttpOnly,
+            MaxAge = MaxAge,
+            SameSite = (Net.Http.Headers.SameSiteMode)SameSite,
+        };
+
+        if (_extensions?.Count > 0)
+        {
+            foreach (var extension in _extensions)
+            {
+                cookie.Extensions.Add(extension);
+            }
+        }
+
+        return cookie;
+    }
 }
diff --git a/src/Http/Http.Features/src/PublicAPI.Unshipped.txt b/src/Http/Http.Features/src/PublicAPI.Unshipped.txt
index a7ea06751b1979b91961f183ab7b2c897a846e94..1ace2c6534a1f8a190c5d1962a88970cebe47820 100644
--- a/src/Http/Http.Features/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Features/src/PublicAPI.Unshipped.txt
@@ -1,4 +1,7 @@
 #nullable enable
+Microsoft.AspNetCore.Http.CookieOptions.CookieOptions(Microsoft.AspNetCore.Http.CookieOptions! options) -> void
+Microsoft.AspNetCore.Http.CookieOptions.CreateCookieHeader(string! name, string! value) -> Microsoft.Net.Http.Headers.SetCookieHeaderValue!
+Microsoft.AspNetCore.Http.CookieOptions.Extensions.get -> System.Collections.Generic.IList<string!>!
 Microsoft.AspNetCore.Http.Features.IHttpExtendedConnectFeature
 Microsoft.AspNetCore.Http.Features.IHttpExtendedConnectFeature.AcceptAsync() -> System.Threading.Tasks.ValueTask<System.IO.Stream!>
 Microsoft.AspNetCore.Http.Features.IHttpExtendedConnectFeature.IsExtendedConnect.get -> bool
diff --git a/src/Http/Http/src/Internal/ResponseCookies.cs b/src/Http/Http/src/Internal/ResponseCookies.cs
index 4c3ba5faa38b28f84df85668d80312ef735aea15..d92d6afdd2561afbe1d62cb3ae1dacc54dfa1779 100644
--- a/src/Http/Http/src/Internal/ResponseCookies.cs
+++ b/src/Http/Http/src/Internal/ResponseCookies.cs
@@ -68,22 +68,11 @@ internal sealed partial class ResponseCookies : IResponseCookies
             }
         }
 
-        var setCookieHeaderValue = new SetCookieHeaderValue(
+        var cookie = options.CreateCookieHeader(
             _enableCookieNameEncoding ? Uri.EscapeDataString(key) : key,
-            Uri.EscapeDataString(value))
-        {
-            Domain = options.Domain,
-            Path = options.Path,
-            Expires = options.Expires,
-            MaxAge = options.MaxAge,
-            Secure = options.Secure,
-            SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite,
-            HttpOnly = options.HttpOnly
-        };
-
-        var cookieValue = setCookieHeaderValue.ToString();
+            Uri.EscapeDataString(value)).ToString();
 
-        Headers.SetCookie = StringValues.Concat(Headers.SetCookie, cookieValue);
+        Headers.SetCookie = StringValues.Concat(Headers.SetCookie, cookie);
     }
 
     /// <inheritdoc />
@@ -112,25 +101,14 @@ internal sealed partial class ResponseCookies : IResponseCookies
             }
         }
 
-        var setCookieHeaderValue = new SetCookieHeaderValue(string.Empty)
-        {
-            Domain = options.Domain,
-            Path = options.Path,
-            Expires = options.Expires,
-            MaxAge = options.MaxAge,
-            Secure = options.Secure,
-            SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite,
-            HttpOnly = options.HttpOnly
-        };
-
-        var cookierHeaderValue = setCookieHeaderValue.ToString()[1..];
+        var cookieSuffix = options.CreateCookieHeader(string.Empty, string.Empty).ToString()[1..];
         var cookies = new string[keyValuePairs.Length];
         var position = 0;
 
         foreach (var keyValuePair in keyValuePairs)
         {
             var key = _enableCookieNameEncoding ? Uri.EscapeDataString(keyValuePair.Key) : keyValuePair.Key;
-            cookies[position] = string.Concat(key, "=", Uri.EscapeDataString(keyValuePair.Value), cookierHeaderValue);
+            cookies[position] = string.Concat(key, "=", Uri.EscapeDataString(keyValuePair.Value), cookieSuffix);
             position++;
         }
 
@@ -200,14 +178,9 @@ internal sealed partial class ResponseCookies : IResponseCookies
             Headers.SetCookie = new StringValues(newValues.ToArray());
         }
 
-        Append(key, string.Empty, new CookieOptions
+        Append(key, string.Empty, new CookieOptions(options)
         {
-            Path = options.Path,
-            Domain = options.Domain,
             Expires = DateTimeOffset.UnixEpoch,
-            Secure = options.Secure,
-            HttpOnly = options.HttpOnly,
-            SameSite = options.SameSite
         });
     }
 
diff --git a/src/Http/Http/test/CookieOptionsTests.cs b/src/Http/Http/test/CookieOptionsTests.cs
new file mode 100644
index 0000000000000000000000000000000000000000..59c9db46fef02933ff801b3d70a474c0df635c81
--- /dev/null
+++ b/src/Http/Http/test/CookieOptionsTests.cs
@@ -0,0 +1,63 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.AspNetCore.Http.Tests;
+
+public class CookieOptionsTests
+{
+    [Fact]
+    public void CopyCtor_AllPropertiesCopied()
+    {
+        var original = new CookieOptions()
+        {
+            Domain = "domain",
+            Expires = DateTime.UtcNow,
+            Extensions = { "ext1", "ext2=v2" },
+            HttpOnly = true,
+            IsEssential = true,
+            MaxAge = TimeSpan.FromSeconds(10),
+            Path = "/foo",
+            Secure = true,
+            SameSite = SameSiteMode.Strict,
+        };
+        var copy = new CookieOptions(original);
+
+        var properties = typeof(CookieOptions).GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+        foreach (var property in properties)
+        {
+            switch (property.Name)
+            {
+                case "Domain":
+                case "Expires":
+                case "HttpOnly":
+                case "IsEssential":
+                case "MaxAge":
+                case "Path":
+                case "Secure":
+                case "SameSite":
+                    Assert.Equal(property.GetValue(original), property.GetValue(copy));
+                    break;
+                case "Extensions":
+                    Assert.NotSame(property.GetValue(original), property.GetValue(copy));
+                    break;
+                default:
+                    Assert.True(false, "Not implemented: " + property.Name);
+                    break;
+            }
+        }
+
+        Assert.Equal(original.Extensions.Count, copy.Extensions.Count);
+        foreach (var value in original.Extensions)
+        {
+            Assert.Contains(value, copy.Extensions);
+        }
+    }
+}
diff --git a/src/Http/Http/test/ResponseCookiesTest.cs b/src/Http/Http/test/ResponseCookiesTest.cs
index 44a0222d791bff8da0432996cf3efb9d78c088f9..6b8d7dddb6a10c1e88886679d86ec7817f15683a 100644
--- a/src/Http/Http/test/ResponseCookiesTest.cs
+++ b/src/Http/Http/test/ResponseCookiesTest.cs
@@ -54,6 +54,49 @@ public class ResponseCookiesTest
         Assert.Equal("The cookie 'TestCookie' has set 'SameSite=None' and must also set 'Secure'.", writeContext.Message);
     }
 
+    [Fact]
+    public void AppendWithExtensions()
+    {
+        var headers = (IHeaderDictionary)new HeaderDictionary();
+        var features = MakeFeatures(headers);
+        var cookies = new ResponseCookies(features);
+        var testCookie = "TestCookie";
+
+        cookies.Append(testCookie, "value", new CookieOptions()
+        {
+            Extensions = { "simple", "key=value" }
+        });
+
+        var cookieHeaderValues = headers.SetCookie;
+        Assert.Single(cookieHeaderValues);
+        Assert.StartsWith(testCookie, cookieHeaderValues[0]);
+        Assert.Contains("path=/", cookieHeaderValues[0]);
+        Assert.Contains("simple;", cookieHeaderValues[0]);
+        Assert.EndsWith("key=value", cookieHeaderValues[0]);
+    }
+
+    [Fact]
+    public void DeleteWithExtensions()
+    {
+        var headers = (IHeaderDictionary)new HeaderDictionary();
+        var features = MakeFeatures(headers);
+        var cookies = new ResponseCookies(features);
+        var testCookie = "TestCookie";
+
+        cookies.Delete(testCookie, new CookieOptions()
+        {
+            Extensions = { "simple", "key=value" }
+        });
+
+        var cookieHeaderValues = headers.SetCookie;
+        Assert.Single(cookieHeaderValues);
+        Assert.StartsWith(testCookie, cookieHeaderValues[0]);
+        Assert.Contains("path=/", cookieHeaderValues[0]);
+        Assert.Contains("expires=Thu, 01 Jan 1970 00:00:00 GMT", cookieHeaderValues[0]);
+        Assert.Contains("simple;", cookieHeaderValues[0]);
+        Assert.EndsWith("key=value", cookieHeaderValues[0]);
+    }
+
     [Fact]
     public void DeleteCookieShouldSetDefaultPath()
     {
@@ -144,7 +187,8 @@ public class ResponseCookiesTest
             Path = "/",
             Expires = time,
             Domain = "example.com",
-            SameSite = SameSiteMode.Lax
+            SameSite = SameSiteMode.Lax,
+            Extensions = { "extension" }
         };
 
         cookies.Delete(testCookie, options);
@@ -157,6 +201,7 @@ public class ResponseCookiesTest
         Assert.Contains("secure", cookieHeaderValues[0]);
         Assert.Contains("httponly", cookieHeaderValues[0]);
         Assert.Contains("samesite", cookieHeaderValues[0]);
+        Assert.Contains("extension", cookieHeaderValues[0]);
     }
 
     [Fact]
diff --git a/src/Security/Authentication/test/CookieTests.cs b/src/Security/Authentication/test/CookieTests.cs
index 27c225208eb3eb23dc3f17a62e866b8c24bfca49..e18a57daaf56264e39ca077bdc408450b9ce9748 100644
--- a/src/Security/Authentication/test/CookieTests.cs
+++ b/src/Security/Authentication/test/CookieTests.cs
@@ -261,6 +261,8 @@ public class CookieTests : SharedAuthenticationTests<CookieAuthenticationOptions
             o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
             o.Cookie.SameSite = SameSiteMode.None;
             o.Cookie.HttpOnly = true;
+            o.Cookie.Extensions.Add("extension0");
+            o.Cookie.Extensions.Add("extension1=value1");
         }, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
 
         using var server1 = host.GetTestServer();
@@ -274,6 +276,8 @@ public class CookieTests : SharedAuthenticationTests<CookieAuthenticationOptions
         Assert.Contains(" secure", setCookie1);
         Assert.Contains(" samesite=none", setCookie1);
         Assert.Contains(" httponly", setCookie1);
+        Assert.Contains(" extension0", setCookie1);
+        Assert.Contains(" extension1=value1", setCookie1);
 
         using var host2 = await CreateHost(o =>
         {
@@ -294,6 +298,7 @@ public class CookieTests : SharedAuthenticationTests<CookieAuthenticationOptions
         Assert.DoesNotContain(" domain=", setCookie2);
         Assert.DoesNotContain(" secure", setCookie2);
         Assert.DoesNotContain(" httponly", setCookie2);
+        Assert.DoesNotContain(" extension", setCookie2);
     }
 
     [Fact]
diff --git a/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectTests.cs b/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectTests.cs
index 99ac5bb819ce77bf813efc8af5160181d46abec0..52a6f4af69b5f937fdf6edc8cc4aa729bb1db375 100644
--- a/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectTests.cs
+++ b/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectTests.cs
@@ -88,6 +88,7 @@ public class OpenIdConnectTests
                 AuthorizationEndpoint = "https://example.com/provider/login"
             };
             opt.NonceCookie.Path = "/";
+            opt.NonceCookie.Extensions.Add("ExtN");
         });
 
         var server = setting.CreateTestServer();
@@ -100,6 +101,7 @@ public class OpenIdConnectTests
         var setCookie = Assert.Single(res.Headers, h => h.Key == "Set-Cookie");
         var nonce = Assert.Single(setCookie.Value, v => v.StartsWith(OpenIdConnectDefaults.CookieNoncePrefix, StringComparison.Ordinal));
         Assert.Contains("path=/", nonce);
+        Assert.Contains("ExtN", nonce);
     }
 
     [Fact]
@@ -139,6 +141,7 @@ public class OpenIdConnectTests
                 AuthorizationEndpoint = "https://example.com/provider/login"
             };
             opt.CorrelationCookie.Path = "/";
+            opt.CorrelationCookie.Extensions.Add("ExtC");
         });
 
         var server = setting.CreateTestServer();
@@ -151,6 +154,7 @@ public class OpenIdConnectTests
         var setCookie = Assert.Single(res.Headers, h => h.Key == "Set-Cookie");
         var correlation = Assert.Single(setCookie.Value, v => v.StartsWith(".AspNetCore.Correlation.", StringComparison.Ordinal));
         Assert.Contains("path=/", correlation);
+        Assert.EndsWith("ExtC", correlation);
     }
 
     [Fact]
diff --git a/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs b/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs
index cbe6273060b860b33bb368f25e631f76753023dc..6fc2f1141d7e6b2eaea97b8d10bcf29b4fc8b4db 100644
--- a/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs
+++ b/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs
@@ -98,20 +98,7 @@ internal sealed class ResponseCookiesWrapper : IResponseCookies, ITrackingConsen
         Debug.Assert(key != null);
         ApplyAppendPolicy(ref key, ref value, options);
 
-        var setCookieHeaderValue = new Net.Http.Headers.SetCookieHeaderValue(
-            Uri.EscapeDataString(key),
-            Uri.EscapeDataString(value))
-        {
-            Domain = options.Domain,
-            Path = options.Path,
-            Expires = options.Expires,
-            MaxAge = options.MaxAge,
-            Secure = options.Secure,
-            SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite,
-            HttpOnly = options.HttpOnly
-        };
-
-        return setCookieHeaderValue.ToString();
+        return options.CreateCookieHeader(Uri.EscapeDataString(key), Uri.EscapeDataString(value)).ToString();
     }
 
     private bool CheckPolicyRequired()
diff --git a/src/Security/CookiePolicy/test/CookieChunkingTests.cs b/src/Security/CookiePolicy/test/CookieChunkingTests.cs
index 21746f11acee4c4ea0c57d4ec9facf9507e68198..c02fef621f88827591b4242994eb4b0eda66bfaa 100644
--- a/src/Security/CookiePolicy/test/CookieChunkingTests.cs
+++ b/src/Security/CookiePolicy/test/CookieChunkingTests.cs
@@ -61,6 +61,25 @@ public class CookieChunkingTests
             }, values);
     }
 
+    [Fact]
+    public void AppendLargeCookieWithExtensions_Chunked()
+    {
+        HttpContext context = new DefaultHttpContext();
+
+        string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        new ChunkingCookieManager() { ChunkSize = 63 }.AppendResponseCookie(context, "TestCookie", testString,
+            new CookieOptions() { Extensions = { "simple", "key=value" } });
+        var values = context.Response.Headers["Set-Cookie"];
+        Assert.Equal(4, values.Count);
+        Assert.Equal<string[]>(new[]
+        {
+                "TestCookie=chunks-3; path=/; simple; key=value",
+                "TestCookieC1=abcdefghijklmnopqrstuv; path=/; simple; key=value",
+                "TestCookieC2=wxyz0123456789ABCDEFGH; path=/; simple; key=value",
+                "TestCookieC3=IJKLMNOPQRSTUVWXYZ; path=/; simple; key=value",
+            }, values);
+    }
+
     [Fact]
     public void GetLargeChunkedCookie_Reassembled()
     {
@@ -129,19 +148,19 @@ public class CookieChunkingTests
         HttpContext context = new DefaultHttpContext();
         context.Request.Headers.Append("Cookie", "TestCookie=chunks-7;TestCookieC1=1;TestCookieC2=2;TestCookieC3=3;TestCookieC4=4;TestCookieC5=5;TestCookieC6=6;TestCookieC7=7");
 
-        new ChunkingCookieManager().DeleteCookie(context, "TestCookie", new CookieOptions() { Domain = "foo.com", Secure = true });
+        new ChunkingCookieManager().DeleteCookie(context, "TestCookie", new CookieOptions() { Domain = "foo.com", Secure = true, Extensions = { "extension" } });
         var cookies = context.Response.Headers["Set-Cookie"];
         Assert.Equal(8, cookies.Count);
         Assert.Equal(new[]
         {
-            "TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-            "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
+            "TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+            "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
         }, cookies);
     }
 
@@ -202,12 +221,13 @@ public class CookieChunkingTests
         {
             Domain = "foo.com",
             Path = "/",
-            Secure = true
+            Secure = true,
+            Extensions = { "extension" }
         };
 
         httpContext.Response.Headers[HeaderNames.SetCookie] = new[]
         {
-                "TestCookie=chunks-7; domain=foo.com; path=/; secure",
+                "TestCookie=chunks-7; domain=foo.com; path=/; secure; other=extension",
                 "TestCookieC1=STUVWXYZ; domain=foo.com; path=/; secure",
                 "TestCookieC2=123456789; domain=foo.com; path=/; secure",
                 "TestCookieC3=stuvwxyz0; domain=foo.com; path=/; secure",
@@ -221,14 +241,14 @@ public class CookieChunkingTests
         Assert.Equal(8, httpContext.Response.Headers[HeaderNames.SetCookie].Count);
         Assert.Equal(new[]
         {
-                "TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure",
-                "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure"
+                "TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension",
+                "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/; secure; extension"
             }, httpContext.Response.Headers[HeaderNames.SetCookie]);
     }
 }
diff --git a/src/Security/CookiePolicy/test/CookieConsentTests.cs b/src/Security/CookiePolicy/test/CookieConsentTests.cs
index e217f18da91061b2e3a159c6d41b2f735513949e..73bfd004860967a0dd9ea86cc74a35d20ac00064 100644
--- a/src/Security/CookiePolicy/test/CookieConsentTests.cs
+++ b/src/Security/CookiePolicy/test/CookieConsentTests.cs
@@ -244,6 +244,7 @@ public class CookieConsentTests
                 Assert.Equal(Http.SameSiteMode.Strict, context.CookieOptions.SameSite);
                 context.CookieName += "1";
                 context.CookieValue += "1";
+                context.CookieOptions.Extensions.Add("extension");
             };
         },
         requestContext => { },
@@ -270,6 +271,7 @@ public class CookieConsentTests
         Assert.Equal("yes1", consentCookie.Value);
         Assert.Equal(Net.Http.Headers.SameSiteMode.Strict, consentCookie.SameSite);
         Assert.NotNull(consentCookie.Expires);
+        Assert.Contains("extension", consentCookie.Extensions);
     }
 
     [Fact]
diff --git a/src/Security/CookiePolicy/test/CookiePolicyTests.cs b/src/Security/CookiePolicy/test/CookiePolicyTests.cs
index a78b7b28185dfdcd470f04f15b41ee6f4eae4b46..bdee31a542688bed0dde3c078b37fb61a450fbf2 100644
--- a/src/Security/CookiePolicy/test/CookiePolicyTests.cs
+++ b/src/Security/CookiePolicy/test/CookiePolicyTests.cs
@@ -367,6 +367,7 @@ public class CookiePolicyTests
                         {
                             HttpOnly = HttpOnlyPolicy.Always,
                             Secure = CookieSecurePolicy.Always,
+                            OnAppendCookie = c => c.CookieOptions.Extensions.Add("extension")
                         });
                         app.UseAuthentication();
                         app.Run(context =>
@@ -401,6 +402,7 @@ public class CookiePolicyTests
         Assert.True(cookie.HttpOnly);
         Assert.True(cookie.Secure);
         Assert.Equal("/", cookie.Path);
+        Assert.Contains("extension", cookie.Extensions);
     }
 
     [Fact]
@@ -416,6 +418,7 @@ public class CookiePolicyTests
                         {
                             HttpOnly = HttpOnlyPolicy.Always,
                             Secure = CookieSecurePolicy.Always,
+                            OnAppendCookie = c => c.CookieOptions.Extensions.Add("ext")
                         });
                         app.UseAuthentication();
                         app.Run(context =>
@@ -452,18 +455,21 @@ public class CookiePolicyTests
         Assert.True(cookie.HttpOnly);
         Assert.True(cookie.Secure);
         Assert.Equal("/", cookie.Path);
+        Assert.Contains("ext", cookie.Extensions);
 
         cookie = SetCookieHeaderValue.Parse(transaction.SetCookie[1]);
         Assert.Equal("TestCookieC1", cookie.Name);
         Assert.True(cookie.HttpOnly);
         Assert.True(cookie.Secure);
         Assert.Equal("/", cookie.Path);
+        Assert.Contains("ext", cookie.Extensions);
 
         cookie = SetCookieHeaderValue.Parse(transaction.SetCookie[2]);
         Assert.Equal("TestCookieC2", cookie.Name);
         Assert.True(cookie.HttpOnly);
         Assert.True(cookie.Secure);
         Assert.Equal("/", cookie.Path);
+        Assert.Contains("ext", cookie.Extensions);
     }
 
     private class TestCookieFeature : IResponseCookiesFeature
diff --git a/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs b/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs
index 6493c526eb660429d90db29fa192da49cb53fda5..20dd051c46f93b58a18b07ff68c06571c618d60c 100644
--- a/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs
+++ b/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs
@@ -173,18 +173,7 @@ internal sealed class ChunkingCookieManager
             return;
         }
 
-        var template = new SetCookieHeaderValue(key)
-        {
-            Domain = options.Domain,
-            Expires = options.Expires,
-            SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite,
-            HttpOnly = options.HttpOnly,
-            Path = options.Path,
-            Secure = options.Secure,
-            MaxAge = options.MaxAge,
-        };
-
-        var templateLength = template.ToString().Length;
+        var templateLength = options.CreateCookieHeader(key, string.Empty).ToString().Length;
 
         // Normal cookie
         if (!ChunkSize.HasValue || ChunkSize.Value > templateLength + value.Length)
@@ -324,15 +313,9 @@ internal sealed class ChunkingCookieManager
             keyValuePairs[i] = KeyValuePair.Create(string.Concat(key, "C", i.ToString(CultureInfo.InvariantCulture)), string.Empty);
         }
 
-        responseCookies.Append(keyValuePairs, new CookieOptions()
+        responseCookies.Append(keyValuePairs, new CookieOptions(options)
         {
-            Path = options.Path,
-            Domain = options.Domain,
-            SameSite = options.SameSite,
-            Secure = options.Secure,
-            IsEssential = options.IsEssential,
             Expires = DateTimeOffset.UnixEpoch,
-            HttpOnly = options.HttpOnly,
         });
     }
 }