kubernetes/kops · error
%s is not a valid S3 URL
Error message
%s is not a valid S3 URL
What it means
VFSPath validates an S3 URL against s3UrlRegexp and converts it to canonical s3://bucket/path form. This error is thrown when the input string doesn't match the S3 URL pattern at all — wrong scheme, missing scheme, an S3 path that isn't parseable, or an entirely non-S3 URL passed where a state-store S3 URL is expected.
Source
Thrown at util/pkg/vfs/s3context.go:364
config, err := awsconfig.LoadDefaultConfig(ctx, awsconfig.WithHTTPClient(shortTimeout))
if err != nil {
return "", fmt.Errorf("failed to load AWS config: %w", err)
}
client := imds.NewFromConfig(config)
metadataRegion, err := client.GetRegion(ctx, &imds.GetRegionInput{})
if err != nil {
return "", fmt.Errorf("getting AWS region from metadata: %w", err)
}
return metadataRegion.Region, nil
}
func VFSPath(url string) (string, error) {
if !s3UrlRegexp.MatchString(url) {
return "", fmt.Errorf("%s is not a valid S3 URL", url)
}
groupNames := s3UrlRegexp.SubexpNames()
result := s3UrlRegexp.FindAllStringSubmatch(url, -1)[0]
captured := map[string]string{}
for i, value := range result {
if value != "" {
captured[groupNames[i]] = value
}
}
bucket := captured["bucket"]
path := captured["path"]
if bucket == "" {
if path == "" {
return "", fmt.Errorf("%s is not a valid S3 URL. No bucket defined.", url)
}
return fmt.Sprintf("s3:/%s", path), nil
}View on GitHub (pinned to 4c8573c808)
Solutions
- Use canonical form: kops create cluster --state s3://<bucket>[/<prefix>], e.g. s3://my-kops-state or s3://my-kops-state/clusters
- Check for scheme typos — must start with s3:// (double slash); remove http(s):// prefixes and stray quotes/whitespace
- If the value comes from $KOPS_STATE_STORE, echo it and re-export without trailing slashes or quotes
- For non-S3 stores, use the correct scheme for that backend (gs:// for GCS, azureblob:// etc.) — VFSPath only accepts S3
- Validate locally by matching against the regex expected by kops before scripting: the URL must have scheme s3:// and a non-empty bucket
Example fix
// before export KOPS_STATE_STORE=my-kops-state kops create cluster ... // error: my-kops-state is not a valid S3 URL // after export KOPS_STATE_STORE=s3://my-kops-state
Defensive patterns
Strategy: validation
Validate before calling
// Validate the state-store URL shape before invoking kops
[[ "$KOPS_STATE_STORE" =~ ^s3://[a-z0-9][a-z0-9.-]{2,62} ]] \
|| { echo "KOPS_STATE_STORE must be s3://<bucket>[/<prefix>], got: $KOPS_STATE_STORE"; exit 1; } Type guard
func isValidS3URL(url string) bool {
return strings.HasPrefix(url, "s3://") && len(url) > len("s3://")
} Prevention
- Always pass --state / KOPS_STATE_STORE in s3://bucket[/prefix] form, never a bare bucket name
- Don't paste S3 console https:// URLs as state store values; use the bucket's s3:// URI
- Quote shell variables to avoid whitespace/character artifacts in the URL
- Check the scheme matches the backend: s3:// for AWS, gs:// for GCS, azureblob:// for Azure
- Validate the value with a quick regex/script check in CI before kops commands run
When it happens
Trigger: s3UrlRegexp.MatchString(url) returns false in VFSPath. Callers pass malformed URLs such as 'mybucket/keys' (no s3:// prefix), 'http://bucket/path', 's3:/bucket' (single slash without path group match), trailing/invalid characters, or a bare hostname. Reached via buildVFSPath when constructing a cluster state store path.
Common situations: Users setting --state to a bucket name without the s3:// scheme (kops create cluster --state mybucket); copying an https console URL of a bucket instead of its S3 URI; quoting/whitespace artifacts from shell variables; typos like s3//bucket or missing slashes.
Related errors
- %s is not a valid S3 URL. No bucket defined.
- error populating configuration: %v
- invalid channel location: %q
- invalid base channel location: %q
- InstanceGroup name is missing
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b112664a9f517744.
Report an issue: GitHub.