googleapis/mcp-toolbox · error
path cannot contain dot segments (..)
Error message
path cannot contain dot segments (..)
What it means
After parsing the relative path, getURL rejects any path segment equal to '..' before resolving against the BaseURL. Dot segments could make the resolved URL climb out of the configured base path scope, so they are refused outright as a path-traversal defense.
Source
Thrown at internal/tools/http/http.go:209
return "", fmt.Errorf("error parsing base URL: %s", err)
}
if baseParsedURL.Scheme == "" || baseParsedURL.Host == "" {
return "", fmt.Errorf("base URL must include scheme and host")
}
relativePath := templatedPath.String()
relParsedURL, err := url.Parse(relativePath)
if err != nil {
return "", fmt.Errorf("error parsing URL path: %s", err)
}
if relParsedURL.Scheme != "" || relParsedURL.Host != "" || relParsedURL.User != nil {
return "", fmt.Errorf("path must be relative and cannot override base host")
}
// Reject dot segments before resolution
for _, segment := range strings.Split(relParsedURL.Path, "/") {
if segment == ".." {
return "", fmt.Errorf("path cannot contain dot segments (..)")
}
}
// Create URL based on BaseURL and Path
// Attach query parameters
parsedURL := baseParsedURL.ResolveReference(relParsedURL)
// Verify final path stays within base path scope
basePath := baseParsedURL.Path
finalPath := parsedURL.Path
if basePath != "/" {
requiredPrefix := strings.TrimSuffix(basePath, "/") + "/"
if finalPath != basePath && !strings.HasPrefix(finalPath, requiredPrefix) {
return "", fmt.Errorf("resolved path %q escapes base path %q", finalPath, basePath)
}
}
// Get existing query parameters from the URLView on GitHub (pinned to 8cc6e09de2)
Solutions
- Remove '..' segments from the path and specify the full intended path from the base (e.g. use '/admin' instead of '/v1/../admin')
- Normalize/resolve the desired path client-side before passing it, so only a clean absolute-relative path reaches the tool
- If traversal out of the base path is genuinely required, configure the tool's BaseURL at the higher-level path
Example fix
// before path: /v1/../admin/settings // after path: /admin/settings
Defensive patterns
Strategy: validation
Validate before calling
for _, seg := range strings.Split(pathParam, "/") {
if seg == ".." {
return fmt.Errorf("dot segments not allowed in path: %q", pathParam)
}
} Type guard
func hasDotSegments(p string) bool {
for _, seg := range strings.Split(p, "/") {
if seg == ".." { return true }
}
return false
} Prevention
- Strip and resolve '..' segments before passing paths to the tool
- Constrain LLM/tool callers to a fixed allowlist of path templates
- Log and reject any user input containing '..' at the application boundary
When it happens
Trigger: getURL is called with a path containing a literal '..' segment such as '/v1/../admin' or '/files/../../etc' — typically produced by user/model-supplied path parameters or naive path joins.
Common situations: LLM-generated tool arguments containing '..'; clients attempting to escape a restricted API prefix; accidental double-resolution where a caller pre-joins paths with '..' to 'go up' a level.
Related errors
- path must be relative and cannot override base host
- resolved path %q escapes base path %q
- URL scheme must be https, got %q
- URL host must be an allowed FHIR host, got %q
- local path %q resolves through a symbolic link to a target o
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/d6e512840a330bc0.
Report an issue: GitHub.