{"record":{"id":"3c522508877f1385","repo":"benbjohnson/litestream","slug":"invalid-s3-access-point-url-s","errorCode":null,"errorMessage":"invalid s3 access point url: %s","messagePattern":"invalid s3 access point url: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica_url.go","lineNumber":114,"sourceCode":"\tcase \"file\":\n\t\tscheme, u.Scheme = u.Scheme, \"\"\n\t\t// Remove query params from path for file URLs\n\t\tu.RawQuery = \"\"\n\t\treturn scheme, \"\", path.Clean(u.String()), nil, nil, nil\n\n\tcase \"\":\n\t\treturn u.Scheme, u.Host, u.Path, nil, nil, fmt.Errorf(\"replica url scheme required: %s\", s)\n\n\tdefault:\n\t\treturn u.Scheme, u.Host, strings.TrimPrefix(path.Clean(u.Path), \"/\"), u.Query(), u.User, nil\n\t}\n}\n\n// parseS3AccessPointURL parses an S3 Access Point URL (s3://arn:...).\nfunc parseS3AccessPointURL(s string) (scheme, host, urlPath string, query url.Values, err error) {\n\tconst prefix = \"s3://\"\n\tif !strings.HasPrefix(strings.ToLower(s), prefix) {\n\t\treturn \"\", \"\", \"\", nil, fmt.Errorf(\"invalid s3 access point url: %s\", s)\n\t}\n\n\tarnWithPath := s[len(prefix):]\n\n\t// Split off query string if present\n\tvar queryStr string\n\tif idx := strings.IndexByte(arnWithPath, '?'); idx != -1 {\n\t\tqueryStr = arnWithPath[idx+1:]\n\t\tarnWithPath = arnWithPath[:idx]\n\t}\n\n\tbucket, key, err := splitS3AccessPointARN(arnWithPath)\n\tif err != nil {\n\t\treturn \"\", \"\", \"\", nil, err\n\t}\n\n\t// Parse query string if present\n\tif queryStr != \"\" {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica_url.go#L96-L132","documentation":"parseS3AccessPointURL handles s3://arn:... Access Point URLs; if the string does not start with the s3:// prefix it cannot be an S3 Access Point URL and this error is returned. It guards the ARN-parsing path from non-S3 inputs.","triggerScenarios":"Calling ParseReplicaURL/ParseReplicaURLWithQuery on a string starting with a case-normalized match for the ARN path but not literally s3:// — practically this occurs when callers invoke parseS3AccessPointURL (via the ARN dispatch) with a URL whose scheme differs, e.g. passing an ARN with a different scheme or a mutated string.","commonSituations":"Copy-pasting an S3 Access Point ARN and altering the scheme; using s3a:// or vendor-compatible endpoints where the Access Point path was expected; string processing that stripped or lowercased the s3:// prefix inconsistently.","solutions":["Ensure the Access Point URL is exactly s3://arn:aws:s3:<region>:<acct>:accesspoint/<name>/... .","Use a plain bucket URL (s3://bucket/path) instead of an ARN if you don't need Access Points.","Check for transcription/normalization bugs that altered the s3:// prefix.","Confirm you're not passing a gs:// or other scheme URL into the S3 Access Point code path."],"exampleFix":"// before\nurl = \"arn:aws:s3:us-east-1:123456789012:accesspoint/myap/db\" // invalid s3 access point url\n// after\nurl = \"s3://arn:aws:s3:us-east-1:123456789012:accesspoint/myap/db\"","handlingStrategy":"validation","validationCode":"if strings.Contains(replicaURL, \"arn:\") && !strings.HasPrefix(strings.ToLower(replicaURL), \"s3://arn:\") {\n    return fmt.Errorf(\"access point ARN URLs must start with s3://arn:\")\n}","typeGuard":"func isS3AccessPointURL(s string) bool { return strings.HasPrefix(strings.ToLower(s), \"s3://arn:\") }","tryCatchPattern":"if _, err := litestream.ParseReplicaURL(rawURL); err != nil {\n    if strings.Contains(err.Error(), \"invalid s3 access point url\") { return fmt.Errorf(\"bad access point URL %q: must be s3://arn:aws:s3:...\", rawURL) }\n    return err\n}","preventionTips":["Copy Access Point ARNs verbatim, keeping the s3:// scheme prefix.","Prefer plain s3://bucket URLs unless Access Points are required.","Avoid string transforms that strip or alter the scheme before parsing.","Validate replica URLs during config load."],"tags":["s3","url","validation","access-point"],"backgroundTag":"invalid-url-format","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}