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
- Validate the custom DirectoryListTemplate with text/template in isolation (template.New(...).Parse(...)) before passing it to StaticWithConfig.
- Ensure the template only references the provided fields: .Name and .Files (a slice of structs with Name, Dir, Size).
- Escape literal curly braces in HTML (use '{{"{{"}}') if you need literal mustaches.
- 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
- Always parse custom templates in isolation first to surface syntax errors clearly.
- Reference only the documented fields (.Name, .Files[].Name/.Dir/.Size).
- Omit DirectoryListTemplate to use the built-in default.
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
- static middleware failed to create sub-filesystem from confi
- timeout must be set
- at least one AllowOrigins is required or UnsafeAllowOriginFu
- echo key-auth middleware requires a validator function
- echo key-auth middleware could not create extractors from Ke
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/d76ab5cf557e05e7.json.
Report an issue: GitHub.