valyala/fasthttp · error

fasthttp: missing location header for http redirect

Error message

fasthttp: missing location header for http redirect

What it means

ErrMissingLocation is returned by fasthttp clients when a response carries a redirect status code (3xx) but no Location header, so the client cannot determine where to redirect the request. Since redirect following is enabled, fasthttp refuses to proceed without a target.

Source

Thrown at client.go:1223

	defer ReleaseRequest(req)

	req.Header.SetMethod(MethodPost)
	req.Header.SetContentTypeBytes(strPostArgsContentType)
	if postArgs != nil {
		if _, err := postArgs.WriteTo(req.BodyWriter()); err != nil {
			return 0, nil, err
		}
	}

	statusCode, body, err = doRequestFollowRedirectsBuffer(req, dst, url, c)

	return statusCode, body, err
}

var (
	// ErrMissingLocation is returned by clients when the Location header is missing on
	// an HTTP response with a redirect status code.
	ErrMissingLocation = errors.New("fasthttp: missing location header for http redirect")
	// ErrTooManyRedirects is returned by clients when the number of redirects followed
	// exceed the max count.
	ErrTooManyRedirects = errors.New("fasthttp: too many redirects detected when doing the request")
	// ErrRedirectBodyStream is returned by clients when a redirect that keeps the request
	// body is received for a request whose body is a stream. The hop that produced the
	// redirect consumed the stream, so the body cannot be sent again.
	ErrRedirectBodyStream = errors.New("fasthttp: cannot follow a body-preserving redirect for a request with a body stream")

	// ErrHostClientRedirectToDifferentScheme is returned when a HostClient follows a redirect to a different protocol.
	ErrHostClientRedirectToDifferentScheme = errors.New("fasthttp: hostclient can't follow redirects to a different protocol," +
		" please use client instead")
)

const defaultMaxRedirectsCount = 16

// Only drain response streams that are known to be small. Reading an unknown
// length stream can block forever (for example, on an event stream), while
// closing a large stream avoids transferring a body the caller discarded.

View on GitHub (pinned to c96f600972)

Solutions

  1. Fix the server/proxy to always set the Location header on 3xx responses
  2. Disable redirect following and handle 3xx responses manually in your code
  3. Log response headers to identify which hop drops Location
  4. If a middleware strips Location, re-add it before the response reaches the client

Example fix

// before: server side returning a bare redirect
ctx.SetStatusCode(fasthttp.StatusFound)
// after: always set Location with the status
ctx.Response.Header.Set("Location", "/login")
ctx.SetStatusCode(fasthttp.StatusFound)
Defensive patterns

Strategy: validation

Validate before calling

loc := resp.Header.Peek(fasthttp.HeaderLocation)
if isRedirect(resp.StatusCode()) && len(loc) == 0 {
    // handle 3xx-without-Location yourself before redirect-following
}

Try / catch

if errors.Is(err, fasthttp.ErrMissingLocation) {
    // inspect resp.StatusCode(); treat server as misbehaving
}

Prevention

When it happens

Trigger: Using HostClient/Client with redirect following enabled and the server replies 301/302/303/307/308 without a Location header; verified by TestExportedErrorStrings coverage.

Common situations: Misconfigured or partially implemented endpoints returning 3xx manually without setting Location; reverse proxies stripping the header; hand-built responses in tests or gateways.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/1f4441aeba566099. Report an issue: GitHub.