gofiber/fiber · error · ErrorInvalidURI
%w: %w
Error message
%w: %w
What it means
When following a redirect, composeRedirectURL re-parses the resolved URI with fasthttp and, if Parse rejects it, returns this dual-wrapped error: fasthttp.ErrorInvalidURI wrapping the concrete parse cause. It signals that the redirect's Location header (combined with the base URL) does not form a valid URI — e.g. a bad port, illegal host bytes, or scheme/host inconsistency that fasthttp's UpdateBytes silently tolerated but Parse caught.
Source
Thrown at client/transport.go:491
}
// composeRedirectURL resolves a redirect target relative to the current request
// URL while rejecting suspicious payloads (e.g. control characters) and
// restricting schemes to HTTP/S so caller-provided Location headers cannot
// trigger arbitrary transports. Redirects from HTTPS to plaintext HTTP are
// rejected to prevent credentials from leaking after a TLS handshake.
//
// It returns the resolved URL along with its host, which the caller compares
// against the previous hop to decide whether origin-scoped credentials still
// apply.
// parsesAsURI reports whether fasthttp reads full as a URI at all, returning the
// reason it does not. Only Parse surfaces that; Update and UpdateBytes discard it.
func parsesAsURI(full []byte) error {
check := fasthttp.AcquireURI()
defer fasthttp.ReleaseURI(check)
if err := check.Parse(nil, full); err != nil {
return fmt.Errorf("%w: %w", fasthttp.ErrorInvalidURI, err)
}
return nil
}
func composeRedirectURL(base string, location []byte, disablePathNormalizing bool) (redirectURL, host string, err error) { //nolint:nonamedreturns // names document the two string results
for _, b := range location {
if b < 0x20 || b == 0x7f {
return "", "", fasthttp.ErrorInvalidURI
}
}
uri := fasthttp.AcquireURI()
defer fasthttp.ReleaseURI(uri)
uri.Update(base)
wasHTTPS := utils.EqualFold(uri.Scheme(), httpsScheme)
uri.UpdateBytes(location)
uri.DisablePathNormalizing = disablePathNormalizingView on GitHub (pinned to a105acad6c)
Solutions
- Disable redirect following (maxRedirects = 0) if you do not trust upstream Location headers, and resolve redirects yourself.
- Validate the Location header with net/url.Parse before following if you implement a custom redirect policy.
- Log the wrapped cause — it specifies the exact parse failure (port, host, scheme).
Example fix
// before
c.SetRedirectPolicy(client.RedirectPolicy{MaxRedirects: 10})
// after (opt out and handle manually)
c.SetRedirectPolicy(client.RedirectPolicy{MaxRedirects: 0})
loc := resp.RawResponse.Header.Peek("Location")
u, err := url.Parse(string(loc))
if err != nil { return fmt.Errorf("bad redirect: %w", err) } Defensive patterns
Strategy: validation
Validate before calling
loc := resp.RawResponse.Header.Peek("Location")
if _, err := url.Parse(string(loc)); err != nil {
return fmt.Errorf("upstream returned bad redirect: %w", err)
} Try / catch
if maxRedirects == 0 || err != nil && errors.Is(err, fasthttp.ErrorInvalidURI) {
// do not follow; surface to caller
} Prevention
- Disable redirect following when you do not trust upstream Location headers.
- Validate Location with net/url.Parse before following if you implement a custom redirect policy.
- Reject HTTPS→HTTP downgrades and non-http(s) schemes explicitly in your policy.
When it happens
Trigger: A server returns a Location header with an invalid port (http://host:abc/x), malformed IPv6 literal, control bytes that survived the earlier filter, or a scheme that fasthttp rejects. The earlier 0x20/0x7f filter and scheme checks (http/https only, HTTPS→HTTP downgrade) run first; reaching this line means a subtler URI defect.
Common situations: Misconfigured upstream returning a broken Location; a reverse proxy rewriting Location incorrectly; an attacker-controlled redirect crafted to stress URI parsers; fasthttp version differences in strictness.
Related errors
- client: HTTPS to HTTP redirect blocked
- ErrRedirectDowngrade
- client: invalid proxy URL: %w
- failed to append certificate
- timeout or cancel
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/e227d5bb5a9054a2.
Report an issue: GitHub.