Server cannot set status after HTTP headers have been sent IIS7.5

asp.net MvcHttpIis 7

asp.net Mvc Problem Overview


Sometimes I get exception in my production environment:

> - Process information

  • Process ID: 3832

  • Process name: w3wp.exe

  • Account name: NT AUTHORITY\NETWORK SERVICE

  • Exception information

    • Exception type: System.Web.HttpException
    • Exception message: Server cannot set status after HTTP headers have been sent.
  • Request information

    • Request URL: http://www.myulr.pl/logon
    • Request path: /logon
    • User host address: 10.11.9.1
    • User: user001
    • Is authenticated: True
    • Authentication Type: Forms
    • Thread account name: NT AUTHORITY\NETWORK SERVICE
  • Thread information

    • Thread ID: 10
    • Thread account name: NT AUTHORITY\NETWORK SERVICE
    • Is impersonating: False

    Stack trace: at System.Web.HttpResponse.set_StatusCode(Int32 value) at
    System.Web.HttpResponseWrapper.set_StatusCode(Int32 value) at
    System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext) at
    System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList(1) filters, Exception exception) at
    System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at
    System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__4() at
    System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.b__0() at
    System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8(1).b__7(IAsyncResult _) at
    System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult(1).End() at
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at
    System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& ompletedSynchronously)

I didn't noticed this error on my test environment what should I check?

I am using ASP.NET MVC 2 (Release Candidate 2)

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

I'll broadly agree with Vagrant on the cause:

  1. your action was executing, writing markup to response stream
  2. the stream was unbuffered forcing the response headers to get written before the markup writing could begin.
  3. Your view encountered a runtime error
  4. Exception handler kicks in trying to set the status code to something else non-200
  5. Fails because the headers have already been sent.

Where I disagree with Vagrant is the "cause no errors in binding" remedy - you could still encounter runtime errors in View binding e.g. null reference exceptions.

A better solution for this is to ensure that Response.BufferOutput = true; before any bytes are sent to the Response stream. e.g. in your controller action or On_Begin_Request in application. This enables server transfers, cookies/headers to be set etc. right the way up to naturally ending response, or calling end/flush.

Of course also check that buffer isn't being flushed/set to false further down in the stack too.

MSDN Reference: HttpResponse.BufferOutput

Solution 2 - asp.net Mvc

Just to add to the responses above. I had this same issue when i first started using ASP.Net MVC and i was doing a Response.Redirect during a controller action:

Response.Redirect("/blah", true);

Instead of returning a Response.Redirect action i should have been returning a RedirectAction:

return Redirect("/blah");

Solution 3 - asp.net Mvc

The HTTP server doesn't send the response header back to the client until you either specify an error or else you start sending data. If you start sending data back to the client, then the server has to send the response head (which contains the status code) first. Once the header has been sent, you can no longer put a status code in the header, obviously.

Here's the usual problem. You start up the page, and send some initial tags (i.e. <head>). The server then sends those tags to the client, after first sending the HTTP response header with an assumed SUCCESS status. Now you start working on the meat of the page and discover a problem. You can not send an error at this point because the response header, which would contain the error status, has already been sent.

The solution is this: Before you generate any content at all, check if there are going to be any errors. Only then, when you have assured that there will be no problems, can you then start sending content, like the tag.

In your case, it seems like you have a login page that processes a POST request from a form. You probably throw out some initial HTML, then check if the username and password are valid. Instead, you should authenticate the user/password first, before you generate any HTML at all.

Solution 4 - asp.net Mvc

I had the same issue with setting StatusCode and then Response.End in HandleUnauthorizedRequest method of AuthorizeAttribute

var ctx = filterContext.HttpContext;
ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden;
ctx.Response.End();

If you are using .NET 4.5+, add this line before Response.StatusCode

filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;

If you are using .NET 4.0, try SuppressFormsAuthenticationRedirectModule.

Solution 5 - asp.net Mvc

How about checking this before doing the redirect:

if (!Response.IsRequestBeingRedirected)
{
   //do the redirect
}

Solution 6 - asp.net Mvc

You are actually trying to redirect a page which has some response to throw. So first you keep the information you have throw in a buffer using response.buffer = true in beginning of the page and then flush it when required using response.flush this error will get fixed

Solution 7 - asp.net Mvc

I remember the part from this exception : "Cannot modify header information - headers already sent by" occurring in PHP. It occurred when the headers were already sent in the redirection phase and any other output was generated e.g.:

echo "hello"; header("Location:http://stackoverflow.com";);

Pardon me and do correct me if I am wrong but I am still learning MS Technologies and I was trying to help.

Solution 8 - asp.net Mvc

I apologize, but I'm adding my 2 cents to the thread just in case anyone has the same problem.

  • I used Forms Authentication in my MVC app
  • But some controller-actions were "anonymous" i.e. allowed to non-authenticated users
  • Sometimes in those actions I would still want users to be redirected to the login form under some condition
  • to do that - I have this in my action method: return new HttpStatusCodeResult(401) - and ASP.NET is super nice to detect this, and it redirects the user to the login page! Magic, right? It even has the proper ReturnUrl parameter etc.

But you see where I'm getting here? I return 401. And ASP.NET redirects the user. Which is essentially returns 302. One status code is replaced with another.

And some IIS servers (just some!) throw this exception. Some don't. - I don't have it on my test serevr, only on my production server (ain't it always the case right o_O)

I know my answer is essentially repeating what's already said here, but sometimes it's just hard to figure out where this overwriting happens exactly.

Solution 9 - asp.net Mvc

We were getting the same error - so this may be useful to some.

For us the cause was super simple. An interface change confused an end user and they were pressing the back button in the browser at a 'bad' time after a form submission (sure we should probably have used a PRG pattern, but we didn't).

We fixed the issue and the user is no longer pressing the back button. Problem solved.

Solution 10 - asp.net Mvc

İf someone still having this problem.Try to use instead of ovverriding

 public void OnActionExecuting(ActionExecutingContext context)
    {
        try
        {

            if (!HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (!HttpContext.Current.Response.IsRequestBeingRedirected)
                {
                   
                    context.Result = new RedirectToRouteResult(
                new RouteValueDictionary {  { "controller", "Login" }, { "action", "Index" } });
                }
            }

        }
        catch (Exception ex)
        {
               new RouteValueDictionary { { "controller", "Login" }, { "action", "Index" } });
        }

    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmarcinnView Question on Stackoverflow
Solution 1 - asp.net MvcstephbuView Answer on Stackoverflow
Solution 2 - asp.net MvcDougView Answer on Stackoverflow
Solution 3 - asp.net MvcVagrantView Answer on Stackoverflow
Solution 4 - asp.net MvcVahidNView Answer on Stackoverflow
Solution 5 - asp.net MvcSandeepView Answer on Stackoverflow
Solution 6 - asp.net MvchemaView Answer on Stackoverflow
Solution 7 - asp.net MvcAdil MehmoodView Answer on Stackoverflow
Solution 8 - asp.net MvcjazzcatView Answer on Stackoverflow
Solution 9 - asp.net MvcniicoView Answer on Stackoverflow
Solution 10 - asp.net MvcEmreView Answer on Stackoverflow