SiteError.comYour friendly guide to HTTP status codes
Status CodesBlog
  1. Home
  2. Blog
  3. Understanding HTTP 511 Network Authentication Required: The Captive Portal Code

Understanding HTTP 511 Network Authentication Required: The Captive Portal Code

September 24, 20267 min read
5xxServer Error

511 Network Authentication Required is a status code almost no application developer will ever write code to return — and that's by design. It exists for one specific job: letting a network (not your server) tell a client "you need to log in to this Wi-Fi, not to whatever you were actually trying to reach." This post covers what 511 promises, why the RFC explicitly forbids origin servers from generating it, and why it's a different animal from 401 even though both are about missing credentials.

What Is a 511?

A 511 tells a client that network-level authentication — not application-level authentication — is standing between it and the internet.

The 511 status code indicates that the client needs to authenticate to gain network access. — RFC 6585, Section 6

In plain English: you're not being denied by the website you're trying to reach — you're being intercepted by the network itself (airport Wi-Fi, a hotel gateway, a coffee shop's router) before your request ever gets there, and that network wants you to log in, accept terms, or pay first.

Don't reach for 511 when what you actually mean is "this user isn't logged into my application." That's 401 or 403. 511 is specifically for the network layer intercepting traffic before it reaches its destination — most application developers will never write code that returns it.

Who's Allowed to Send a 511

This is the detail that makes 511 different from almost every other status code in the spec: the RFC doesn't just describe what the code means, it restricts who's allowed to generate it.

The 511 status SHOULD NOT be generated by origin servers; it is intended for use by intercepting proxies that are interposed as a means of controlling access to the network. — RFC 6585, Section 6

That's a deliberate, load-bearing restriction. Your application server — the thing running your Express or Next.js code — has no business ever emitting a 511. It's meant for the network gear sitting in front of every destination: the router or gateway in a coffee shop, hotel, or airport that's silently intercepting outbound requests and answering on behalf of whatever site the client was actually trying to reach.

The Captive Portal Story

The RFC's own example is the clearest explanation of why this code exists at all. A network operator wants to require login (or accept-terms, or payment) before granting internet access. It does this by identifying unauthenticated clients — historically by MAC address — and blocking all of their traffic except requests to a dedicated "login server":

GET /index.htm HTTP/1.1
Host: www.example.com

The client thinks it's asking www.example.com for a page. It's actually talking to the network's login server, which intercepts the request and answers with a 511:

HTTP/1.1 511 Network Authentication Required
Content-Type: text/html
 
<html>
   <head>
      <title>Network Authentication Required</title>
      <meta http-equiv="refresh"
            content="0; url=https://login.example.net/">
   </head>
   <body>
      <p>You need to <a href="https://login.example.net/">
      authenticate with the local network</a> in order to gain
      access.</p>
   </body>
</html>

The RFC also specifies what the response shouldn't contain: "the 511 response SHOULD NOT contain a challenge or the login interface itself, because browsers would show the login interface as being associated with the originally requested URL, which may cause confusion." In other words, don't put the actual login form inline in the 511 body — redirect the user to the login server's own page instead, as the example above does with the meta refresh, so the address bar clearly shows the user is on the network's login page, not on www.example.com.

Why This Isn't Just 401

401 and 511 both mean "you need to authenticate before I'll give you what you asked for" — but the two relationships they describe are completely different:

  • 401 is between the client and the destination application — the origin server itself is saying "log into me."
  • 511 is between the client and the network it's connected to — some intermediary between the client and the destination is saying "log into me before you can even reach the destination."

The distinction matters practically, not just semantically. Software that speaks HTTP but isn't a browser — an API client, a background sync job, an IoT device — has no way to distinguish "the destination server wants credentials" from "the network silently swapped in a login page" unless the status code tells it. A 401 from api.example.com means retry with credentials against api.example.com. A response claiming to be from api.example.com that's actually a captive portal page would, without 511, look exactly like a broken or hijacked API response — the client can't tell it's not really talking to the API at all. 511 exists specifically to make that distinguishable, which is also why the RFC prohibits caching it: Responses with the 511 status code MUST NOT be stored by a cache.

511 vs 401 vs 407

CodeWho's asking for credentialsRelationshipStandard?
401 UnauthorizedThe destination applicationClient ↔ origin serverYes (RFC 9110)
407 Proxy Authentication RequiredA proxy the client explicitly configuredClient ↔ known, configured proxyYes (RFC 9110)
511 Network Authentication RequiredAn intercepting network gatewayClient ↔ network the client didn't choose to authenticate withYes (RFC 6585)

407 and 511 can look similar — both involve an intermediary rather than the final destination — but 407 is for a proxy the client knowingly configured (and expects to authenticate with), while 511 is for a network silently intercepting traffic the client believed was going straight through.

Why Application Developers Rarely Touch This

Because the RFC scopes 511 to intercepting proxies and network gateways, there's no meaningful "Returning 511 Correctly" section for Express or Next.js route handlers the way there is for 401 or 403 — writing that code in your application server would be misusing the status code. If you're building the login-server side of an actual captive portal (embedded router firmware, a hotel Wi-Fi gateway), the shape of the response is exactly the RFC's example above: a 511 status, Content-Type: text/html, and a redirect to a separate login page rather than an inline form.

What you're more likely to build instead is a client that handles 511 gracefully — an API client or mobile app that, on receiving one, recognizes it isn't a real API error and surfaces "you need to sign in to this Wi-Fi network" instead of treating it as a failed request to your own backend.

Common Pitfalls

  1. Returning 511 from application code to mean "please log in." That's 401. 511 is reserved for network-layer interception, not your app telling a user their session expired.
  2. Putting the actual login form in the 511 response body. The RFC explicitly recommends against this — redirect to a separate login page so the browser's address bar doesn't misleadingly associate the login UI with the original destination.
  3. Caching a 511 response. The spec prohibits it outright, and for good reason: a cached captive-portal page served up after the client actually authenticates would incorrectly block access to a site that's now reachable.
  4. Building API clients that don't handle 511 as a distinct case. If your client treats every non-2xx response as "the API failed," a captive portal response will look like a cryptic API error instead of what it actually is — surfacing it distinctly ("connect to this Wi-Fi network first") is a better user experience than a generic error toast.

Wrapping Up

511 exists to solve a narrow but real problem: letting non-browser clients tell the difference between "the destination rejected me" and "the network I'm on hijacked my request." The rules of thumb:

  • 511 means the network wants you to authenticate, not the destination server
  • The RFC says origin servers SHOULD NOT generate it — it's for intercepting proxies and gateways only
  • It's distinct from 401 (destination auth) and 407 (a proxy you chose to use)
  • Never cache a 511 response, and never embed the login form directly in it — redirect instead

For more, see our pages on 511 Network Authentication Required, 401 Unauthorized, and 407 Proxy Authentication Required, or our 401 Unauthorized post for the destination-side half of this story.

Full Reference

511 Network Authentication Required

The client needs to authenticate to gain network access, often used by captive portals.

Related Status Codes

💥500Internal Server Error🚧501Not Implemented🌉502Bad Gateway🔧503Service Unavailable⌛504Gateway Timeout📡505HTTP Version Not Supported🔄506Variant Also Negotiates💾507Insufficient Storage🔁508Loop Detected🧩510Not Extended📶511Network Authentication Required
Back to Blog

Popular Status Codes

  • 200 OK
  • 301 Moved Permanently
  • 302 Found
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable

Compare Codes

  • 401 vs 403
  • 301 vs 302
  • 404 vs 410
  • 500 vs 502
  • Compare any codes →

Categories

  • Informational
  • Success
  • Redirection
  • Client Error
  • Server Error
  • NGINX
  • Cloudflare
  • AWS ELB
  • Microsoft IIS

Tools

  • Cheat Sheet
  • Status Code Quiz
  • URL Checker
  • API Playground
  • Blog

© 2026 SiteError.com. All rights reserved.