By Ben Hoffman

2010-05-05 22:02:43 8 Comments

When I use Response.Redirect(...) to redirect my form to a new page I get the error:

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll
An exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll but was not handled in user code

My understanding of this is that the error is being caused by the webserver aborting the remainder of the page the response.redirect was called on.

I know I can add a second parameter to Response.Redirect that is called endResponse. If I set endResponse to True I still get the error but if I set it to False then I do not. I am pretty sure though that that means the webserver is running the rest of the page I redirected away from. Which would seem to be inefficient to say the least. Is there a better way to do this? Something other than Response.Redirect or is there a way to force the old page to stop loading where I will not get a ThreadAbortException?


@Martin Smith 2010-05-05 22:09:55

This is just how Response.Redirect(url, true) works. It throws the ThreadAbortException to abort the thread. Just ignore that exception. (I presume it is some global error handler/logger where you see it?)

An interesting related discussion Is Response.End() Considered Harmful?.

@spender 2010-05-05 22:13:06

Aborting a thread seems like a really heavy handed way to deal with premature end of response. I find it strange that the framework wouldn't prefer to re-use the thread instead of spinning up a new one to take its place.

@Marko 2010-05-25 07:34:36

I had that problem too.

Try using Server.Transfer instead of Response.Redirect

Worked for me.

@Joel Beckham 2011-10-11 15:19:56

Server.Transfer should still be throwing a ThreadAbortException:, so it is not a recommended solution.

@Marcel 2013-09-18 13:05:54

Server.Transfer will not send a redirect to the user. It has a different purpose altogether!

@mzonerz 2016-08-17 14:10:27

Server.transfer and responce.redirect are different

@Joel Fillmore 2010-05-05 22:28:24

The correct pattern is to call the Redirect overload with endResponse=false and make a call to tell the IIS pipeline that it should advance directly to the EndRequest stage once you return control:

Response.Redirect(url, false);

This blog post from Thomas Marquardt provides additional details, including how to handle the special case of redirecting inside an Application_Error handler.

@IsmailS 2010-11-26 07:46:35

It executes code after Context.ApplicationInstance.CompleteRequest();. Why? Will I have to return from the event handler conditionally?

@Joel Fillmore 2010-11-29 18:56:49

@Ismail: The old version of Redirect throws a ThreadAbortException to prevent execution of any subsequent code. The newer, preferred version doesn't throw, but you are responsible for returning control early if you have additional code in the handler.

@BornToCode 2015-07-14 01:39:22

I think it's more accurate to say "the second overload" rather than The old version of Redirect phrase you use in your comment, it's not like MS changed the implementation, it's just another overload.

@Abs 2017-01-05 01:13:14

I do not think this is an ideal pattern. You are asking the page not to end the response and continue the execution and then completing request programmatically. But what about the rendering of aspx page and event handlers? not ending the response means, it will finish rendering the aspx page before hitting "completeRequest()". Now if I am using a server side property in my page say a session variable to determine valid login, which if expire will throw a null exception before even redirecting. And the only way to fix that is to make the endResponse back to true.

@Hawkeye 2017-07-25 16:33:46

@Abs I believe your statement "not ending the response means, it will finish rendering the aspx page before hitting 'completeRequest()'" is not correct. According to MSDN ( the page would render after the page load and other control events.

@Hawkeye 2017-07-25 17:18:04

So adding will CompleteRequest() will "bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event" Source:…

@DaniDev 2018-01-31 19:23:12

Was going to up vote this answer, but that page code continued to execute. This is not ideal in my case. Much cleaner to handle or ignore the "ThreadAbortException"

@Jorge 2013-02-28 17:00:09

What I do is catch this exception, together with another possible exceptions. Hope this help someone.

 catch (ThreadAbortException ex1)
 catch(Exception ex)

@Kiquenet 2015-10-05 09:05:31

Better avoid ThreadAbortException exception than catch and do nothing ?

@Ortund 2012-06-28 06:51:33

I know I'm late, but I've only ever had this error if my Response.Redirect is in a Try...Catch block.

Never put a Response.Redirect into a Try...Catch block. It's bad practice


In response to @Kiquenet's comment, here's what I would do as an alternative to putting the Response.Redirect into the Try...Catch block.

I'd break up the method/function into two steps.

Step one inside the Try...Catch block performs the requested actions and sets a "result" value to indicate success or failure of the actions.

Step two outside of the Try...Catch block does the redirect (or doesn't) depending on what the "result" value is.

This code is far from perfect and probably should not be copied since I haven't tested it

public void btnLogin_Click(UserLoginViewModel model)
    bool ValidLogin = false; // this is our "result value"
        using (Context Db = new Context)
            User User = new User();

            if (String.IsNullOrEmpty(model.EmailAddress))
                ValidLogin = false; // no email address was entered
                User = Db.FirstOrDefault(x => x.EmailAddress == model.EmailAddress);

            if (User != null && User.PasswordHash == Hashing.CreateHash(model.Password))
                ValidLogin = true; // login succeeded
    catch (Exception ex)
        throw ex; // something went wrong so throw an error

    if (ValidLogin)
        // do something to indicate that the login failed.

@Ortund 2016-11-03 15:20:34

@Kiquenet please see my updated answer for an example of what I would do. Not to say its the best course, but it is a viable alternative I think.

@interesting-name-here 2016-12-29 22:07:27

Did not have the issue until I wrapped my code in a try, catch... I wonder what other code calls cause this behavior in .NET

@SammuelMiranda 2015-09-03 19:52:30

i even tryed to avoid this, just in case doing the Abort on the thread manually, but i rather leave it with the "CompleteRequest" and move on - my code has return commands after redirects anyway. So this can be done

public static void Redirect(string VPathRedirect, global::System.Web.UI.Page Sender)
    Sender.Response.Redirect(VPathRedirect, false);

@Maxim Lavrov 2014-01-17 15:23:26

Also I tried other solution, but some of the code executed after redirect.

public static void ResponseRedirect(HttpResponse iResponse, string iUrl)
        ResponseRedirect(iResponse, iUrl, HttpContext.Current);

    public static void ResponseRedirect(HttpResponse iResponse, string iUrl, HttpContext iContext)
        iResponse.Redirect(iUrl, false);


        iResponse.BufferOutput = true;

So if need to prevent code execution after redirect

   //other code
  // code not to be executed
catch(ThreadAbortException){}//do there id nothing here
catch(Exception ex)

@Maxim Lavrov 2014-01-17 16:20:25

just follow up by the Jorge answer. This will ectually remove the logging of the Thread abort exception.

@manuell 2014-01-17 16:24:44

When someone ask why he gets an Exception, telling him to just play with try..catch is not an answer. See the accepted answer. I commented on your answer while reviewing "late answer"

@NickG 2016-06-13 13:08:12

That has the same effect as putting false for the 2nd argument of Response.Redirect, but the "false" is a nicer solution than capturing the ThreadAbortException. I don't see that there is ever a good reason to do it this way.

@JacquesB 2012-10-18 15:09:43

There is no simple and elegant solution to the Redirect problem in ASP.Net WebForms. You can choose between the Dirty solution and the Tedious solution

Dirty: Response.Redirect(url) sends a redirect to the browser, and then throws a ThreadAbortedException to terminate the current thread. So no code is executed past the Redirect()-call. Downsides: It is bad practice and have performance implications to kill threads like this. Also, ThreadAbortedExceptions will show up in exception logging.

Tedious: The recommended way is to call Response.Redirect(url, false) and then Context.ApplicationInstance.CompleteRequest() However, code execution will continue and the rest of the event handlers in the page lifecycle will still be executed. (E.g. if you perform the redirect in Page_Load, not only will the rest of the handler be executed, Page_PreRender and so on will also still be called - the rendered page will just not be sent to the browser. You can avoid the extra processing by e.g. setting a flag on the page, and then let subsequent event handlers check this flag before before doing any processing.

(The documentation to CompleteRequest states that it "Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution". This can easily be misunderstood. It does bypass further HTTP filters and modules, but it doesn't bypass further events in the current page lifecycle.)

The deeper problem is that WebForms lacks a level of abstraction. When you are in a event handler, you are already in the process of building a page to output. Redirecting in an event handler is ugly because you are terminating a partially generated page in order to generate a different page. MVC does not have this problem since the control flow is separate from rendering views, so you can do a clean redirect by simply returning a RedirectAction in the controller, without generating a view.

@mcfea 2015-01-02 22:58:45

I believe the best description of webforms I ever heard was "lie sauce."

@Jess 2015-09-30 14:43:33

I love the amount of detail in this answer. Better than the accepted answer

@Jess 2015-09-30 14:48:44

If you use the dirty option, You can turn off break on ThreadAbortException in Visual Studio. DEBUG > Exceptions.... Expand CLR > System.Threading > Uncheck System.Threading.ThreadAbortException.

@Abs 2017-01-05 01:15:05

thank god we have someone with proper answer, and this should be the highest voted answer.

@Sagar Shirke 2017-01-05 13:07:32

In my case this exception is not coming for each and every time, only for few times in between it is occuring. Means If and clicking on same button of Live application it is working but when same link and same button is clicked from other machine it is giving System.Threading.ThreadAbortException. Any idea why it not happening everytime??

@jo0ls 2019-12-16 12:58:33

If you pass false, and don't bother checking the flag, then the browser will receive the entire page with a 302 status code in the header - found. The malicious user can simply change the status to 200, and gain access to the entire page, which is very insecure.

@M4N 2010-05-05 22:11:21

Response.Redirect() throws an exception to abort the current request.

This KB article describes this behavior (also for the Request.End() and Server.Transfer() methods).

For Response.Redirect() there exists an overload:

Response.Redirect(String url, bool endResponse)

If you pass endResponse=false, then the exception is not thrown (but the runtime will continue processing the current request).

If endResponse=true (or if the other overload is used), the exception is thrown and the current request will immediately be terminated.

@spender 2010-05-05 22:08:47

Here's the official line on the problem (I couldn't find the latest, but I don't think the situation has changed for later versions of .net)

@Ryan Gates 2015-02-04 14:59:15

@svick Regardless of link rot, link only answers aren't really great answers. I think that links are fantastic, but they should never be the only piece of information in your answer.

Related Questions

Sponsored Content

44 Answered Questions

3 Answered Questions

[SOLVED] Thread was being aborted when we use

  • 2013-02-01 05:21:11
  • Kavita
  • 67771 View
  • 14 Score
  • 3 Answer
  • Tags:   c#

1 Answered Questions

[SOLVED] ASP.NET Response.Redirect( ) Error

  • 2011-06-02 21:59:01
  • user521694
  • 10765 View
  • 10 Score
  • 1 Answer
  • Tags:   c#

1 Answered Questions

[SOLVED] Can "EndResponse" increase performance of ASP.Net page

1 Answered Questions

How can I use together jquery,ajax and mysql?

  • 2014-05-13 09:38:53
  • user3627624
  • 151 View
  • 0 Score
  • 1 Answer
  • Tags:   c# jquery mysql ajax

3 Answered Questions

[SOLVED] Response.Redirect exception

  • 2011-01-04 11:11:00
  • Tedd Hansen
  • 8185 View
  • 6 Score
  • 3 Answer
  • Tags:

3 Answered Questions

[SOLVED] System.Threading.ThreadAbortException caused by Response.Redirect

3 Answered Questions

[SOLVED] Response.Redirect throwing error

  • 2011-11-02 14:12:10
  • DirtyKalb
  • 9943 View
  • 4 Score
  • 3 Answer
  • Tags:   c#

2 Answered Questions

[SOLVED] response.redirect - dealing with threadabortedexception

  • 2011-05-05 15:39:56
  • Dustin Davis
  • 316 View
  • 1 Score
  • 2 Answer
  • Tags:

Sponsored Content