labstack/echo · error
ErrInvalidRedirectCode
ErrInvalidRedirectCode
Error message
invalid redirect status code
What it means
ErrInvalidRedirectCode is returned by Context.Redirect when the status code is outside the HTTP 3xx redirect range (code < 300 || code > 308). Only 300-308 are valid redirect status codes per HTTP spec; passing anything else (200, 404, 201, etc.) is a programmer error.
Source
Thrown at httperror.go:32
ErrBadRequest = &httpError{http.StatusBadRequest} // 400
ErrUnauthorized = &httpError{http.StatusUnauthorized} // 401
ErrForbidden = &httpError{http.StatusForbidden} // 403
ErrNotFound = &httpError{http.StatusNotFound} // 404
ErrMethodNotAllowed = &httpError{http.StatusMethodNotAllowed} // 405
ErrRequestTimeout = &httpError{http.StatusRequestTimeout} // 408
ErrStatusRequestEntityTooLarge = &httpError{http.StatusRequestEntityTooLarge} // 413
ErrUnsupportedMediaType = &httpError{http.StatusUnsupportedMediaType} // 415
ErrTooManyRequests = &httpError{http.StatusTooManyRequests} // 429
ErrInternalServerError = &httpError{http.StatusInternalServerError} // 500
ErrBadGateway = &httpError{http.StatusBadGateway} // 502
ErrServiceUnavailable = &httpError{http.StatusServiceUnavailable} // 503
)
// The following errors fall into 500 (InternalServerError) category
var (
ErrValidatorNotRegistered = errors.New("validator not registered")
ErrRendererNotRegistered = errors.New("renderer not registered")
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
ErrCookieNotFound = errors.New("cookie not found")
ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte")
ErrInvalidListenerNetwork = errors.New("invalid listener network")
)
// HTTPStatusCoder is an interface that errors can implement to produce status code for HTTP response
type HTTPStatusCoder interface {
StatusCode() int
}
// StatusCode returns status code from err if it implements HTTPStatusCoder interface.
// If err does not implement the interface, it returns 0.
func StatusCode(err error) int {
var sc HTTPStatusCoder
if errors.As(err, &sc) {
return sc.StatusCode()
}
return 0View on GitHub (pinned to 05489dc173)
Solutions
- Use a valid redirect code: 301 (MovedPermanently), 302 (Found), 303 (SeeOther), 307 (TemporaryRedirect), or 308 (PermanentRedirect)
- For non-redirect responses use c.String/c.JSON/c.HTML instead of c.Redirect
- Define named constants for your redirect codes to avoid magic numbers
Example fix
// before c.Redirect(http.StatusCreated, "/new") // 201 — error // after c.Redirect(http.StatusFound, "/new") // 302 — ok
Defensive patterns
Strategy: validation
Validate before calling
// Validate redirect code before calling Redirect
func validRedirectCode(code int) bool {
return code >= 300 && code <= 308
}
if !validRedirectCode(code) {
return fmt.Errorf("invalid redirect code: %d", code)
}
c.Redirect(code, url) Try / catch
if err := c.Redirect(code, url); err != nil {
if errors.Is(err, echo.ErrInvalidRedirectCode) {
return echo.NewHTTPError(http.StatusInternalServerError, "misconfigured redirect")
}
return err
} Prevention
- Use named constants from net/http (StatusMovedPermanently, StatusFound, etc.) instead of magic numbers
- Centralize redirect helper functions that enforce valid codes
- Unit test redirect handlers with the expected 3xx codes
When it happens
Trigger: Calling c.Redirect(http.StatusCreated, url) or c.Redirect(200, url) or c.Redirect(404, url). Any status code outside [300,308] triggers it.
Common situations: Using http.StatusCreated (201) or http.StatusOK (200) by mistake instead of http.StatusMovedPermanently (301) or http.StatusFound (302). Copy-pasting a status constant from elsewhere.
Related errors
- ErrValidatorNotRegistered
- redirectConfig is missing redirect function
- invalid redirect code for add trailing slash middleware
- invalid redirect code for remove trailing slash middleware
- failed to parse value, err: %w
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/c1318dff867211e7.json.
Report an issue: GitHub.