slimtoolkit/slim · error
root %q is not absolute
Error message
root %q is not absolute
What it means
The fastcgi RoundTrip transport requires the FastCGI application's document root (t.Root) to be an absolute filesystem path because the FastCGI protocol sends the ROOT document path to the backend. Before dialing the backend, buildEnv strips IPv6 brackets from the host and validates that Root starts with '/'; if it does not, the request cannot be converted into a valid FastCGI PARAMS block and this error is returned to the caller of RoundTrip.
Source
Thrown at pkg/app/master/probe/http/internal/fastcgi.go:141
// buildEnv returns a set of CGI environment variables for the request.
func (t FastCGITransport) buildEnv(r *http.Request) (map[string]string, error) {
// Separate remote IP and port; more lenient than net.SplitHostPort
var ip, port string
if idx := strings.LastIndex(r.RemoteAddr, ":"); idx > -1 {
ip = r.RemoteAddr[:idx]
port = r.RemoteAddr[idx+1:]
} else {
ip = r.RemoteAddr
}
// Remove [] from IPv6 addresses
ip = strings.Replace(ip, "[", "", 1)
ip = strings.Replace(ip, "]", "", 1)
// make sure file root is absolute
if !path.IsAbs(t.Root) {
return nil, fmt.Errorf("root %q is not absolute", t.Root)
}
root := t.Root
fpath := r.URL.Path
scriptName := fpath
docURI := fpath
// split "actual path" from "path info" if configured
var pathInfo string
if splitPos := t.splitPos(fpath); splitPos > -1 {
docURI = fpath[:splitPos]
pathInfo = fpath[splitPos:]
// Strip PATH_INFO from SCRIPT_NAME
scriptName = strings.TrimSuffix(scriptName, pathInfo)
}
// SCRIPT_FILENAME is the absolute path of SCRIPT_NAMEView on GitHub (pinned to 81940d17fa)
Solutions
- Set t.Root to an absolute filesystem path (must start with '/'), e.g. "/srv/www/current/public".
- If the root comes from config/env, convert it with filepath.Abs before constructing the transport.
- Verify the value is non-empty; an empty Root is not absolute and fails the same check.
- On macOS/Windows-style inputs, ensure separators and drive prefixes are converted to the container/OS absolute form before use.
Example fix
// before
transport := &fastcgi.Transport{Root: "public", ...}
// after
root, err := filepath.Abs("public")
if err != nil {
return err
}
transport := &fastcgi.Transport{Root: root, ...} Defensive patterns
Strategy: validation
Validate before calling
if !filepath.IsAbs(root) || root == "" {
abs, err := filepath.Abs(root)
if err != nil {
return fmt.Errorf("cannot resolve fastcgi root %q: %w", root, err)
}
root = abs
}
transport := &fastcgi.Transport{Root: root, ...} Type guard
func isAbsoluteRoot(root string) bool {
return root != "" && filepath.IsAbs(root)
} Try / catch
resp, err := client.Do(req)
if err != nil {
if strings.Contains(err.Error(), "is not absolute") {
return nil, fmt.Errorf("fix fastcgi transport Root to an absolute path: %w", err)
}
return nil, err
} Prevention
- Always build the transport Root with filepath.Abs or an absolute constant
- Validate configured root paths at startup, before any requests are made
- Never leave Root empty; empty strings fail the IsAbs check
When it happens
Trigger: Calling http.Client.Do (or Transport.RoundTrip) on a client whose Transport is the fastcgi handler transport with a target whose Root field was set to a relative path (e.g. "www", "./public", or an empty string) instead of an absolute path like "/var/www".
Common situations: Configuring the FastCGI target root from a config flag or environment variable that holds a relative directory; forgetting to prefix the root with '/' when hand-building the fastcgi handler; passing a URL-style path ("/app" vs actual filesystem path) or leaving Root unset (empty string is not absolute).
Related errors
- No global params
- no service image
- malformed Kubernetes workload name
- fcgi: invalid header version
- unknown sensor mode
AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31).
Data as JSON: /api/errors/1fad225d7d705aba.
Report an issue: GitHub.