benbjohnson/litestream · error
invalid s3 access point url: %s
Error message
invalid s3 access point url: %s
What it means
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.
Source
Thrown at replica_url.go:114
case "file":
scheme, u.Scheme = u.Scheme, ""
// Remove query params from path for file URLs
u.RawQuery = ""
return scheme, "", path.Clean(u.String()), nil, nil, nil
case "":
return u.Scheme, u.Host, u.Path, nil, nil, fmt.Errorf("replica url scheme required: %s", s)
default:
return u.Scheme, u.Host, strings.TrimPrefix(path.Clean(u.Path), "/"), u.Query(), u.User, nil
}
}
// parseS3AccessPointURL parses an S3 Access Point URL (s3://arn:...).
func parseS3AccessPointURL(s string) (scheme, host, urlPath string, query url.Values, err error) {
const prefix = "s3://"
if !strings.HasPrefix(strings.ToLower(s), prefix) {
return "", "", "", nil, fmt.Errorf("invalid s3 access point url: %s", s)
}
arnWithPath := s[len(prefix):]
// Split off query string if present
var queryStr string
if idx := strings.IndexByte(arnWithPath, '?'); idx != -1 {
queryStr = arnWithPath[idx+1:]
arnWithPath = arnWithPath[:idx]
}
bucket, key, err := splitS3AccessPointARN(arnWithPath)
if err != nil {
return "", "", "", nil, err
}
// Parse query string if present
if queryStr != "" {View on GitHub (pinned to 4ed7a308f6)
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.
Example fix
// before url = "arn:aws:s3:us-east-1:123456789012:accesspoint/myap/db" // invalid s3 access point url // after url = "s3://arn:aws:s3:us-east-1:123456789012:accesspoint/myap/db"
Defensive patterns
Strategy: validation
Validate before calling
if strings.Contains(replicaURL, "arn:") && !strings.HasPrefix(strings.ToLower(replicaURL), "s3://arn:") {
return fmt.Errorf("access point ARN URLs must start with s3://arn:")
} Type guard
func isS3AccessPointURL(s string) bool { return strings.HasPrefix(strings.ToLower(s), "s3://arn:") } Try / catch
if _, err := litestream.ParseReplicaURL(rawURL); err != nil {
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) }
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- heartbeat URL must be a valid HTTP or HTTPS URL
- file replica path required
- bucket required for gs replica URL
- oss: invalid url scheme
- replica url scheme required: %s
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/3c522508877f1385.
Report an issue: GitHub.