labstack/echo · error

invalid redirect code for add trailing slash middleware

Error message

invalid redirect code for add trailing slash middleware

What it means

Returned by AddTrailingSlashConfig.ToMiddleware when RedirectCode is non-zero and falls outside the valid redirect range [300, 308]. A RedirectCode of 0 is valid — it means 'rewrite internally without an HTTP redirect'. Any other value must be a 3xx status code, mirroring the check echo.Context.Redirect performs.

Source

Thrown at middleware/slash.go:45

//
// Usage `Echo#Pre(AddTrailingSlash())`
func AddTrailingSlash() echo.MiddlewareFunc {
	return AddTrailingSlashWithConfig(AddTrailingSlashConfig{})
}

// AddTrailingSlashWithConfig returns an AddTrailingSlash middleware with config or panics on invalid configuration.
func AddTrailingSlashWithConfig(config AddTrailingSlashConfig) echo.MiddlewareFunc {
	return toMiddlewareOrPanic(config)
}

// ToMiddleware converts AddTrailingSlashConfig to middleware or returns an error for invalid configuration
func (config AddTrailingSlashConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
	if config.Skipper == nil {
		config.Skipper = DefaultSkipper
	}
	if config.RedirectCode != 0 && (config.RedirectCode < http.StatusMultipleChoices || config.RedirectCode > http.StatusPermanentRedirect) {
		// this is same check as `echo.context.Redirect()` does, but we can check this before even serving the request.
		return nil, errors.New("invalid redirect code for add trailing slash middleware")
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c *echo.Context) error {
			if config.Skipper(c) {
				return next(c)
			}

			req := c.Request()
			url := req.URL
			path := url.Path
			qs := c.QueryString()
			if !strings.HasSuffix(path, "/") {
				path += "/"
				uri := path
				if qs != "" {
					uri += "?" + qs
				}

View on GitHub (pinned to 05489dc173)

Solutions

  1. Use a 3xx code such as http.StatusMovedPermanently (301) or http.StatusPermanentRedirect (308).
  2. If you want internal forwarding (no HTTP redirect), leave RedirectCode as 0 (the default).
  3. Double-check the constant you pass is in the 300-308 range.
  4. Use config.ToMiddleware() to surface the error instead of panicking.

Example fix

// before (200 is not a redirect code)
m := middleware.AddTrailingSlashWithConfig(middleware.AddTrailingSlashConfig{RedirectCode: http.StatusOK})
// after
m := middleware.AddTrailingSlashWithConfig(middleware.AddTrailingSlashConfig{RedirectCode: http.StatusMovedPermanently})
Defensive patterns

Strategy: validation

Validate before calling

func isValidRedirectCode(code int) bool {
    return code == 0 || (code >= 300 && code <= 308)
}

Prevention

When it happens

Trigger: Calling AddTrailingSlashWithConfig(AddTrailingSlashConfig{RedirectCode: 200}) or any code < 300 or > 308 (e.g., 301 is fine; 309, 200, 404 are not).

Common situations: Developer passes a status code thinking 0 means 'use default 301' (it does not — it disables the redirect); or copies a code constant that is not a 3xx (e.g., StatusOK).

Related errors


AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04). Data as JSON: /data/errors/6d7b9d4722f33c4a.json. Report an issue: GitHub.