90

When I call Response.Redirect(someUrl) I get the following HttpException:

Cannot redirect after HTTP headers have been sent.

Why do I get this? And how can I fix this issue?

B--rian
  • 5,578
  • 10
  • 38
  • 89
Samuel Meacham
  • 10,215
  • 7
  • 44
  • 50

15 Answers15

124

According to the MSDN documentation for Response.Redirect(string url), it will throw an HttpException when "a redirection is attempted after the HTTP headers have been sent". Since Response.Redirect(string url) uses the Http "Location" response header (http://en.wikipedia.org/wiki/HTTP_headers#Responses), calling it will cause the headers to be sent to the client. This means that if you call it a second time, or if you call it after you've caused the headers to be sent in some other way, you'll get the HttpException.

One way to guard against calling Response.Redirect() multiple times is to check the Response.IsRequestBeingRedirected property (bool) before calling it.

// Causes headers to be sent to the client (Http "Location" response header)
Response.Redirect("http://www.stackoverflow.com");
if (!Response.IsRequestBeingRedirected)
    // Will not be called
    Response.Redirect("http://www.google.com");
Samuel Meacham
  • 10,215
  • 7
  • 44
  • 50
  • 2
    Yup exactly. This happens quite easily with ASP.NET MVC 4 and the Exception filters, etc. You also cannot change the HTTP Response Status Code once a redirect 301/302 has been issued. – Jaans Jul 04 '13 at 11:56
  • I solved the issue by making all the properties on my page 'static' – Sal Dec 01 '13 at 09:11
  • 5
    making your properties static is a dangerous solution – prospector Feb 13 '15 at 02:34
  • How can the redirect be called a second time unless the ThreadAbortException (from the first time) is caught? :} "Calling Redirect is equivalent to calling Redirect with the second parameter (`endResponse`) set to true." – user2864740 Jun 08 '15 at 23:50
  • 4
    It's weird, but in a legacy webforms application `Response.IsRequestBeingRedirected` is false and I'm still getting this same exception (inside `Application_EndRequest` event method in Global.asax). I can't understand why. – Alisson Reinaldo Silva Aug 07 '18 at 11:57
  • Never use static properties in a web application or variable contents will leak between requests. @Sal – Anders Lindén Jan 22 '22 at 11:42
17

Once you send any content at all to the client, the HTTP headers have already been sent. A Response.Redirect() call works by sending special information in the headers that make the browser ask for a different URL.

Since the headers were already sent, asp.net can't do what you want (modify the headers)

You can get around this by a) either doing the Redirect before you do anything else, or b) try using Response.Buffer = true before you do anything else, to make sure that no output is sent to the client until the whole page is done executing.

mbudnik
  • 2,087
  • 15
  • 34
Philip Rieck
  • 32,368
  • 11
  • 87
  • 99
  • For me it doesn't work. I use .NET, MVC and I have a call inside controller's method. I still receive exception, although redirection happens. – FrenkyB Feb 21 '19 at 01:22
8

A Redirect can only happen if the first line in an HTTP message is "HTTP/1.x 3xx Redirect Reason".

If you already called Response.Write() or set some headers, it'll be too late for a redirect. You can try calling Response.Headers.Clear() before the Redirect to see if that helps.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
3

Using return RedirectPermanent(myUrl) worked for me

Vasilis
  • 41
  • 1
3

Just check if you have set the buffering option to false (by default its true). For response.redirect to work,

  1. Buffering should be true,
  2. you should not have sent more data using response.write which exceeds the default buffer size (in which case it will flush itself causing the headers to be sent) therefore disallowing you to redirect.
2

You can also use below mentioned code

Response.Write("<script type='text/javascript'>"); Response.Write("window.location = '" + redirect url + "'</script>");Response.Flush();
Dipanki Jadav
  • 360
  • 3
  • 7
1

My Issue got resolved by adding the Exception Handler to handle "Cannot redirect after HTTP headers have been sent". this Error as shown below code

catch (System.Threading.ThreadAbortException)
        {
            // To Handle HTTP Exception "Cannot redirect after HTTP headers have been sent".
        }
        catch (Exception e)
        {//Here you can put your context.response.redirect("page.aspx");}
1

There is one simple answer for this: You have been output something else, like text, or anything related to output from your page before you send your header. This affect why you get that error.

Just check your code for posible output or you can put the header on top of your method so it will be send first.

DucDigital
  • 4,580
  • 9
  • 49
  • 97
1

If you are trying to redirect after the headers have been sent (if, for instance, you are doing an error redirect from a partially-generated page), you can send some client Javascript (location.replace or location.href, etc.) to redirect to whatever URL you want. Of course, that depends on what HTML has already been sent down.

Brad
  • 11
  • 1
1

I solved the problem using: Response.RedirectToRoute("CultureEnabled", RouteData.Values); instead of Response.Redirect.

utilsit
  • 141
  • 1
  • 8
1

Be sure that you don't use Responses' methods like Response.Flush(); before your redirecting part.

1_bug
  • 5,505
  • 4
  • 50
  • 58
1

Error Cannot redirect after HTTP headers have been sent.

System.Web.HttpException (0x80004005): Cannot redirect after HTTP headers have been sent.

Suggestion

If we use asp.net mvc and working on same controller and redirect to different Action then you do not need to write..
Response.Redirect("ActionName","ControllerName");
its better to use only
return RedirectToAction("ActionName");
or
return View("ViewName");

Ram Samuj
  • 11
  • 2
0

If you get Cannot redirect after HTTP headers have been sent then try this below code.

HttpContext.Current.Server.ClearError();
// Response.Headers.Clear();
HttpContext.Current.Response.Redirect("/Home/Login",false);
durron597
  • 31,968
  • 17
  • 99
  • 158
0

The redirect function probably works by using the 'refresh' http header (and maybe using a 30X code as well). Once the headers have been sent to the client, there is not way for the server to append that redirect command, its too late.

Nathan
  • 11,938
  • 12
  • 55
  • 62
-3

There are 2 ways to fix this:

  1. Just add a return statement after your Response.Redirect(someUrl); ( if the method signature is not "void", you will have to return that "type", of course ) as so:

    Response.Redirect("Login.aspx");

    return;

Note the return allows the server to perform the redirect...without it, the server wants to continue executing the rest of your code...

  1. Make your Response.Redirect(someUrl) the LAST executed statement in the method that is throwing the exception. Replace your Response.Redirect(someUrl) with a string VARIABLE named "someUrl", and set it to the redirect location... as follows:

//......some code

string someUrl = String.Empty

.....some logic

if (x=y)
{
    // comment (original location of Response.Redirect("Login.aspx");)
    someUrl = "Login.aspx";
}

......more code

// MOVE your Response.Redirect to HERE (the end of the method):

Response.Redirect(someUrl);
return; 
  • sorry but this makes not any sense to me. What should (in a void-returning method) that redundant `return` do? The `return` only defines that the method is completed. But when there's not any code left, the method is completed anyway. And storing an url in a variable doesn't change anything, I mean: why should it? The string is the same. The compiled thing doesn't make any difference between a string and a variable containing a string...: think about `x = 5`, so x is 5 but 5 is also 5. even 10/2 would be 5... makes no difference neither – Matthias Burger Apr 04 '19 at 07:29