hashicorp/terraform · error
error parsing S3 URL
Error message
error parsing S3 URL: %s
What it means
Returned by detectS3PathStyle (3-label host case) when url.Parse rejects 'https://<region>.amazonaws.com/<parts...>'. Because the region and parts came from the input, a parse failure means invalid characters in the region or key path. The %s is the url.Parse error.
Solutions
- URL-encode the object key segments.
- Use the explicit s3::https:// form with a verified URL.
- Rename the S3 object to remove problematic characters.
Example fix
# before (space in key) source = "us-east-1.amazonaws.com/bucket/my module.zip" # after source = "s3::https://us-east-1.amazonaws.com/bucket/my%20module.zip"
Defensive patterns
Strategy: validation
Validate before calling
// URL-encode the S3 key before constructing a path-style URL.
// enc := url.PathEscape(key)
// u := fmt.Sprintf("https://%s.amazonaws.com/%s", region, enc)
// if _, err := url.Parse(u); err != nil { return err } Prevention
- URL-encode object keys.
- Avoid spaces/control characters in S3 keys.
- Use the explicit s3::https:// form.
When it happens
Trigger: A path-style S3 source whose region or object key contains control characters, spaces, or bad percent-encoding causes url.Parse to fail.
Common situations: Spaces or special characters in the object key pasted verbatim; non-ASCII region/bucket characters.
Related errors
- error parsing BitBucket URL
- error parsing GCS URL
- error parsing GitHub URL
- can't delete default state
- error parsing Git SSH URL
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/38253dbd302f6a86.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getmodules/moduleaddrs/detect_s3.go:46
return detectS3PathStyle(hostParts[0], parts[1:])
} else if len(hostParts) == 4 {
return detectS3OldVhostStyle(hostParts[1], hostParts[0], parts[1:])
} else if len(hostParts) == 5 && hostParts[1] == "s3" {
return detectS3NewVhostStyle(hostParts[2], hostParts[0], parts[1:])
} else {
return "", false, fmt.Errorf(
"URL is not a valid S3 URL")
}
}
return "", false, nil
}
func detectS3PathStyle(region string, parts []string) (string, bool, error) {
urlStr := fmt.Sprintf("https://%s.amazonaws.com/%s", region, strings.Join(parts, "/"))
url, err := url.Parse(urlStr)
if err != nil {
return "", false, fmt.Errorf("error parsing S3 URL: %s", err)
}
return "s3::" + url.String(), true, nil
}
func detectS3OldVhostStyle(region, bucket string, parts []string) (string, bool, error) {
urlStr := fmt.Sprintf("https://%s.amazonaws.com/%s/%s", region, bucket, strings.Join(parts, "/"))
url, err := url.Parse(urlStr)
if err != nil {
return "", false, fmt.Errorf("error parsing S3 URL: %s", err)
}
return "s3::" + url.String(), true, nil
}
func detectS3NewVhostStyle(region, bucket string, parts []string) (string, bool, error) {
urlStr := fmt.Sprintf("https://s3.%s.amazonaws.com/%s/%s", region, bucket, strings.Join(parts, "/"))
url, err := url.Parse(urlStr)View on GitHub (pinned to d32a084675)