---
title: "Debugging cookie problems in ASP.NET Core"
description: "How to debug cookie problems in ASP.NET Core: cookies the browser rejects, cookies missing from requests, lost cookies and the SameSite rules behind them."
url: https://nestenius.se/net/debugging-cookie-problems/
date: 2023-10-09
author: "Tore Nestenius"
category: ".NET"
tags: ["authentication"]
site: https://nestenius.se/
---

# Debugging cookie problems in ASP.NET Core

## Troubleshooting cookie problems in ASP.NET Core

Having answered over 1000 questions on [Stack Overflow](https://stackoverflow.com/users/68490/tore-nestenius), I’ve found that cookie-related issues are a frequent challenge for developers using ASP.NET Core, especially when implementing authentication and OpenID Connect.

Cookie problems can, in my experience, be categorized into the following categories:

- **Browser Rejection**  
    Cookies provided by the server that aren't accepted by the browser.
- **Browser Omission**  
    Cookies in the browser are not included in requests to the server.
- **Lost cookies**  
    Cookies that are lost on the way to the server.

In this post, we’ll explore common ASP.NET Core cookie problems, such as browser rejection, missing cookies in requests, and lost cookies. You’ll learn practical tips to identify, diagnose, and resolve these issues, ensuring smoother authentication flows and a more reliable application experience.

## Cookies rejected by the browser

When setting a cookie, we use the **set-cookie** response header, often accompanied by the **secure** and **samesite** attributes. Below is an example illustrating the setting of five common cookies:

```http
HTTP/1.1 200 OK Set-Cookie: NormalCookie=NormalValue;Path=/ 
Set-Cookie: NormalCookieWitSecure=NormalValueSecure;Path=/;
secure Set-Cookie: StrictCookie=StrictValue;Path=/;SameSite=Strict 
Set-Cookie: LaxCookie=LaxValue;Path=/;SameSite=Lax 
Set-Cookie: NoneCookie=NoneValue;Path=/;SameSite=None;Secure …
```

(Note: This article will not discuss the details of the **path**, **domain**, and the **HttpOnly** attribute. The **HttpOnly** attribute is all about restricting JavaScript from accessing cookies.). I recommend setting the **HttpOnly** attribute on every cookie that never needs to be accessed by JavaScript.

## How can I tell if the browser accepts a cookie?

The first step in troubleshooting cookie problems is to verify that the browser has accepted the cookie.

To see which cookies it has received and accepted, open the browser developer tools (**F12**) in **Chrome** and look under **Application -> Storage -> Cookies**.

![How to view the cookies for the current page.](https://nestenius.se/_astro/chrome-devtools-application-cookies-panel-samesite.DnXz5jiQ_gKPKq.webp)

If the expected cookies are not found here, then head over to the **Network** tab, locate the request that sets the cookie, and then click on the **Cookies** sub-tab:

![How to view the cookies for a given request in the network tab.](https://nestenius.se/_astro/chrome-devtools-network-cookies-tab-response-set-cookie.DB87n3VC_ZcrrtB.webp)

Rejected cookies are highlighted in yellow. Hovering over the information (i) icon displays reasons for the blockage. As shown in the example below:

![Example of rejected cookies in the browser](https://nestenius.se/_astro/chrome-devtools-set-cookie-blocked-secure-attribute-http.NIt1W2lE_1Mj3cA.webp)

You can also activate the “**Has blocked cookies**” checkbox to only show requests with blocked response cookies.

Some of the most common reasons for blocking are:

- Using **samesite=none** without the **secure** attribute
- Trying to set a cookie with the **secure** attribute over **HTTP://**
- Too large cookies; keep the cookie size below 4000 bytes for maximum browser compatibility. 

## Cookies not included in requests

If you have concluded that the browser has accepted the cookie and it is found under **Application -> Storage**, great! One step forward! What’s next?

There are a few reasons why the browser might decide not to include cookies in outgoing requests:

Some of the reasons for blocking are:

- Protocol Mismatch  
    Cookies with the **secure** attribute will not be included in requests over **HTTP**.
- **Incorrect samesite**  
    For cross-site requests, you must use:

    - **samesite=none;secure** when you need to support **GET** & **POST** in requests to another site

    - **samesite=lax** when you only need to support **GET** requests across sites.

- **Cross-Origin Resource Sharing (CORS)**  
    We won’t go into CORS in this blog post. CORS can be problematic when you do API requests from JavaScript using the XMLHttpRequest or Fetch APIs.

Under the **network tab**, you can see why a cookie was not included in the request, as shown in the example below:  

![Example of how the browser blocks cookies due to the samesite attribute.](https://nestenius.se/_astro/chrome-devtools-samesite-strict-cookie-blocked-cross-site.BQzwgbj-_Z1hLyzJ.webp)

## Common SameSite Cookie Problems

Some of the common **samesite** problems that I see are:

- **SameSite=none cookies**  
    Cookies set with the **samesite=none** attribute must also be marked with the **secure** attribute. This means that they must always be used over HTTPS, a common problem, for example, when working with OpenID Connect.
- **Missing samesite header?**  
    All cookies that you set should have a **samesite** attribute. Otherwise, you might end up with unexpected issues where browsers will start to block them in certain circumstances.

    For example, **Firefox** writes this warning to the console when you try to set a cookie without a valid samesite attribute:

|   _Cookie “NormalCookie” does not have a proper “SameSite” attribute value. Soon, cookies without the “SameSite” attribute or with an invalid value will be treated as “Lax”. This means that the cookie will no longer be sent in third-party contexts. If your application depends on this cookie being available in such contexts, please add the “SameSite=None“ attribute to it. To know more about the “SameSite“ attribute, read_ [_https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite_](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie)    |
| --- |

## Which samesite value should you use?

Some guidance about what value to use:

- **Strict**  
    Use this value for cookies that should only be used within the same site. For example, consider using this value for your session cookie. Using strict cookies provides the maximum protection against Cross-Site Requests.
- **Lax**  
    This is the new default for cookies, which only includes the cookie GET requests across sites.
- **None**  
    Use this value for cookies that should be included in all site requests. This value must be set together with the **secure** attribute. This is the least secure option. This makes the cookies behave like they behaved before the **samesite** concept was introduced. 

## Cookies in ASP.NET Core

What can go wrong when we use cookies in ASP.NET Core?

When you use the cookie authentication handler, the default session cookie is set as follows:

```http
Set-Cookie: .AspNetCore.Cookies=xxxxxxx; path=/; secure; samesite=lax; httponly
```

This is a sensible default. You might be tempted to set the session cookie to **samesite=strict**, as follows:

```csharp
builder.Services.AddAuthentication()
       .AddCookie(opt =>                 
	   {
           opt.Cookie.SameSite = SameSiteMode.Strict;                 
       });
```

If you just use local authentication (like ASP.NET Core Identity), that is usually fine. But, when you use it together with OpenID Connect, you will have problems, as shown in the image below:

![OpenID Connect Cookies blocked by the browser](https://nestenius.se/_astro/chrome-devtools-cookies-samesite-strict-blocked-warning.BrEVGz8H_Z1iUjma.webp)

## OpenID Connect, cookies, and IdentityServer

When you work with OpenID Connect, plenty of cookies will be involved. For example, if you use [Duende IdentityServer](https://duendesoftware.com/), then the following cookies are involved during authentication:

![Overview of the cookies used when authenticating using OpenID Connect](https://nestenius.se/_astro/aspnetcore-openidconnect-cookie-flow-browser-identityserver.jICGSTCe_Z1VhVTV.webp)

Not properly configuring and understanding these cookies is a common source of problems.

## Same domain but different ports

You might think that when you have multiple sites on the same domain but on different ports, they would have separate cookie jars:

- [http://www.mydomain.com](http://www.mydomain.com)
- [https://www.mydomain.com](https://www.mydomain.com)
- [http://www.mydomain.com:8080](http://www.mydomain.com:8080)

But it turns out that they will all share the same cookie jar. The cookies are tied to the domain, not the port or scheme.

## Summary

I hope the steps outlined above can help you troubleshoot your cookie problems. Here are some tips for healthier and more secure cookies:

- **Always use HTTPS**  
    Most cookie problems will go away when you move your traffic to HTTPS. Using HTTPS today is also a must If you care about security.
- **Set samesite**  
    Always add the correct samesite attribute; this is a must today.
- Add the **secure** and **HttpOny** attribute  
    Securing our cookies and all sensitive cookies should always have these two attributes set.
- **Do research the path and domain attributes**  
    They can be used to further restrict to what domain (including sub-domains) and path the cookies should be included on.

## Resources

- [Tips for testing and debugging SameSite-by-default and "SameSite=None; Secure" cookies](https://www.chromium.org/updates/same-site/test-debug/)
- [SameSite cookie recipes](https://web.dev/articles/samesite-cookie-recipes#use-cases-for-cross-site-or-third-party-cookies)
- [SameSite cookies explained](https://web.dev/articles/samesite-cookies-explained)
- [Changes to SameSite Cookie Behavior – A Call to Action for Web Developers](https://hacks.mozilla.org/2020/08/changes-to-samesite-cookie-behavior/)
- [Handle SameSite cookie changes in Chrome browser](https://learn.microsoft.com/en-us/entra/identity-platform/howto-handle-samesite-cookie-changes-chrome-browser)
- [Work with SameSite cookies in ASP.NET](https://learn.microsoft.com/en-us/aspnet/samesite/system-web-samesite)
- [Understanding "same-site" and "same-origin"](https://web.dev/articles/same-site-same-origin)

## Related posts
- [What's new in ASP.NET Core authentication in .NET 11](https://nestenius.se/net/whats-new-in-asp-net-core-authentication-in-net-11/)

- [Debugging OpenID Connect claim problems in ASP.NET Core](https://nestenius.se/net/missing-openid-connect-claims-in-asp-net-core/)
- [IdentityServer – IdentityResource vs. ApiResource vs. ApiScope](https://nestenius.se/net/identityserver-identityresource-vs-apiresource-vs-apiscope/)
- [Troubleshooting JwtBearer authentication problems in ASP.NET Core](https://nestenius.se/net/troubleshooting-jwtbearer-authentication-problems-in-asp-net-core/)
- [Improving ASP.NET Core Security By Putting Your Cookies On A Diet](https://nestenius.se/net/improving-asp-net-core-security-by-putting-your-cookies-on-a-diet/)

## Related Training Workshops

- [ASP.NET Core fundamentals](https://tn-data.se/courses/asp-net-core-fundamentals/)
- [Web security fundamentals](https://tn-data.se/courses/web-security-fundamentals/)

## Feedback, comments, found any bugs?

Let me know if you have any feedback, anything I missed, or any bugs/typos. You can find my contact details on the [contact page](https://nestenius.se/contact/).
