labstack/echo · error

echo static middleware directory list template parsing error

Error message

echo static middleware directory list template parsing error: %w

What it means

Returned by StaticConfig.ToMiddleware() when text/template.Parse fails on config.DirectoryListTemplate. The default template is the built-in directoryListHTMLTemplate; providing a custom template with invalid Go template syntax (unclosed actions, bad pipelines, undefined functions) causes this startup-time error.

Source

Thrown at middleware/static.go:197

	if config.Root == "" {
		config.Root = "." // For security we want to restrict to CWD.
	} else {
		config.Root = path.Clean(config.Root) // fs.Open is very picky about ``, `.`, `..` in paths, so remove some of them up.
	}

	if config.Skipper == nil {
		config.Skipper = DefaultStaticConfig.Skipper
	}
	if config.Index == "" {
		config.Index = DefaultStaticConfig.Index
	}
	if config.DirectoryListTemplate == "" {
		config.DirectoryListTemplate = directoryListHTMLTemplate
	}

	dirListTemplate, tErr := template.New("index").Parse(config.DirectoryListTemplate)
	if tErr != nil {
		return nil, fmt.Errorf("echo static middleware directory list template parsing error: %w", tErr)
	}

	var once *sync.Once
	var fsErr error
	currentFS := config.Filesystem
	if config.Filesystem == nil {
		once = &sync.Once{}
	} else if config.Root != "." {
		tmpFs, fErr := fs.Sub(config.Filesystem, path.Join(".", config.Root))
		if fErr != nil {
			return nil, fmt.Errorf("static middleware failed to create sub-filesystem from config.Root, error: %w", fErr)
		}
		currentFS = tmpFs
	}

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

View on GitHub (pinned to 05489dc173)

Solutions

  1. Validate the custom DirectoryListTemplate with text/template in isolation (template.New(...).Parse(...)) before passing it to StaticWithConfig.
  2. Ensure the template only references the provided fields: .Name and .Files (a slice of structs with Name, Dir, Size).
  3. Escape literal curly braces in HTML (use '{{"{{"}}') if you need literal mustaches.
  4. Leave DirectoryListTemplate empty to use the built-in default template.

Example fix

// before
tmpl := `<ul>{{ range .Files}<li>{{.Name}}</li>{{end}}</ul>` // missing '}'
// after
tmpl := `<ul>{{ range .Files }}<li>{{.Name}}</li>{{end}}</ul>`
Defensive patterns

Strategy: validation

Validate before calling

// Parse the template before passing it to StaticWithConfig.
func validateDirTemplate(tmpl string) error {
    _, err := template.New("index").Parse(tmpl)
    return err
}

if err := validateDirTemplate(cfg.DirectoryListTemplate); err != nil {
    return fmt.Errorf("bad directory list template: %w", err)
}

Prevention

When it happens

Trigger: Setting StaticConfig.DirectoryListTemplate to a string containing malformed template syntax such as '{{ .Name' (unclosed), '{{ foo . }}' (undefined function), or invalid pipeline operators. Returned before any request is served.

Common situations: Customizing the directory listing UI with a hand-written template that has a typo; upgrading Echo and reusing an old template referencing fields that changed; copy-pasting HTML with literal '{{' that the template engine interprets as actions.

Related errors


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