{"record":{"id":"38253dbd302f6a86","repo":"hashicorp/terraform","slug":"error-parsing-s3-url-s","errorCode":null,"errorMessage":"error parsing S3 URL: %s","messagePattern":"error parsing S3 URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/detect_s3.go","lineNumber":46,"sourceCode":"\t\t\treturn detectS3PathStyle(hostParts[0], parts[1:])\n\t\t} else if len(hostParts) == 4 {\n\t\t\treturn detectS3OldVhostStyle(hostParts[1], hostParts[0], parts[1:])\n\t\t} else if len(hostParts) == 5 && hostParts[1] == \"s3\" {\n\t\t\treturn detectS3NewVhostStyle(hostParts[2], hostParts[0], parts[1:])\n\t\t} else {\n\t\t\treturn \"\", false, fmt.Errorf(\n\t\t\t\t\"URL is not a valid S3 URL\")\n\t\t}\n\t}\n\n\treturn \"\", false, nil\n}\n\nfunc detectS3PathStyle(region string, parts []string) (string, bool, error) {\n\turlStr := fmt.Sprintf(\"https://%s.amazonaws.com/%s\", region, strings.Join(parts, \"/\"))\n\turl, err := url.Parse(urlStr)\n\tif err != nil {\n\t\treturn \"\", false, fmt.Errorf(\"error parsing S3 URL: %s\", err)\n\t}\n\n\treturn \"s3::\" + url.String(), true, nil\n}\n\nfunc detectS3OldVhostStyle(region, bucket string, parts []string) (string, bool, error) {\n\turlStr := fmt.Sprintf(\"https://%s.amazonaws.com/%s/%s\", region, bucket, strings.Join(parts, \"/\"))\n\turl, err := url.Parse(urlStr)\n\tif err != nil {\n\t\treturn \"\", false, fmt.Errorf(\"error parsing S3 URL: %s\", err)\n\t}\n\n\treturn \"s3::\" + url.String(), true, nil\n}\n\nfunc detectS3NewVhostStyle(region, bucket string, parts []string) (string, bool, error) {\n\turlStr := fmt.Sprintf(\"https://s3.%s.amazonaws.com/%s/%s\", region, bucket, strings.Join(parts, \"/\"))\n\turl, err := url.Parse(urlStr)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getmodules/moduleaddrs/detect_s3.go#L28-L64","documentation":"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.","triggerScenarios":"A path-style S3 source whose region or object key contains control characters, spaces, or bad percent-encoding causes url.Parse to fail.","commonSituations":"Spaces or special characters in the object key pasted verbatim; non-ASCII region/bucket characters.","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."],"exampleFix":"# before (space in key)\nsource = \"us-east-1.amazonaws.com/bucket/my module.zip\"\n\n# after\nsource = \"s3::https://us-east-1.amazonaws.com/bucket/my%20module.zip\"","handlingStrategy":"validation","validationCode":"// URL-encode the S3 key before constructing a path-style URL.\n// enc := url.PathEscape(key)\n// u := fmt.Sprintf(\"https://%s.amazonaws.com/%s\", region, enc)\n// if _, err := url.Parse(u); err != nil { return err }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["URL-encode object keys.","Avoid spaces/control characters in S3 keys.","Use the explicit s3::https:// form."],"tags":["s3","url-parsing","encoding"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}