caddyserver/caddy · error

module %s is not a precompressor; is %T

Error message

module %s is not a precompressor; is %T

What it means

`caddy file-server --precompressed X` startup error: the module http.precompressed.X exists but its instance does not implement encode.Precompressed. The message reports the concrete Go type of the instance. This guards against a module squatting the precompressed namespace without the required interface.

Source

Thrown at modules/caddyhttp/fileserver/command.go:144

		handler := caddytpl.Templates{FileRoot: root}
		handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "templates", nil))
	}

	handler := FileServer{Root: root}

	if len(precompressed) != 0 {
		// logic mirrors modules/caddyhttp/fileserver/caddyfile.go case "precompressed"
		var order []string
		for _, compression := range precompressed {
			modID := "http.precompressed." + compression
			mod, err := caddy.GetModule(modID)
			if err != nil {
				return caddy.ExitCodeFailedStartup, fmt.Errorf("getting module named '%s': %v", modID, err)
			}
			inst := mod.New()
			precompress, ok := inst.(encode.Precompressed)
			if !ok {
				return caddy.ExitCodeFailedStartup, fmt.Errorf("module %s is not a precompressor; is %T", modID, inst)
			}
			if handler.PrecompressedRaw == nil {
				handler.PrecompressedRaw = make(caddy.ModuleMap)
			}
			handler.PrecompressedRaw[compression] = caddyconfig.JSON(precompress, nil)
			order = append(order, compression)
		}
		handler.PrecompressedOrder = order
	}

	if browse {
		handler.Browse = &Browse{RevealSymlinks: revealSymlinks, FileLimit: fileLimit}
	}

	handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "file_server", nil))

	route := caddyhttp.Route{HandlersRaw: handlers}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Check the reported type — if it's your plugin, implement encode.Precompressed properly
  2. Remove or update the offending plugin in the xcaddy build
  3. Use only well-maintained precompressor plugins

Example fix

// plugin must satisfy the interface
var _ encode.Precompressed = (*MyPrecompress)(nil)
Defensive patterns

Strategy: type-guard

Type guard

// plugin compile-time interface guard
var _ encode.Precompressed = (*MyPrecompress)(nil)

Prevention

When it happens

Trigger: A third-party module registers itself under http.precompressed.<name> but its New() returns a type lacking the Precompressed interface (Encode()/AcceptEncoding()-style methods).

Common situations: Custom/xcaddy plugins misusing the http.precompressed namespace; version mismatches where the plugin targets an older Caddy API.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/2d4a1239739efaa8. Report an issue: GitHub.