kubernetes/kops · error
%s is not a valid S3 URL. No bucket defined.
Error message
%s is not a valid S3 URL. No bucket defined.
What it means
VFSPath matched the S3 URL regex but captured neither a bucket nor a path. The best-known case is the bare URL 's3://' or an equivalent like 's3:///' — the scheme is right but there is no bucket to operate on, so kOps throws this error instead of building a bucket-less path.
Source
Thrown at util/pkg/vfs/s3context.go:379
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
}
return fmt.Sprintf("s3://%s%s", bucket, path), nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Set the full store including the bucket: export KOPS_STATE_STORE=s3://<your-bucket> and re-run the command
- Check the variable feeding the URL is actually populated (echo "$BUCKET") — an empty expansion yields s3://
- In scripts, fail early: [ -n "$BUCKET" ] || { echo 'BUCKET not set'; exit 1; } before building the s3:// URL
- Fix templating/CI config so the state-store field is not rendered empty; use a required-input check in your pipeline
Example fix
// before: empty variable collapses the URL
kops create cluster --state "s3://${BUCKET}"
// error: s3:// is not a valid S3 URL. No bucket defined.
// after
: "${BUCKET:?BUCKET must be set}"
kops create cluster --state "s3://${BUCKET}" Defensive patterns
Strategy: validation
Validate before calling
// Require a non-empty bucket part in the S3 URL
url="${KOPS_STATE_STORE}"
rest="${url#s3://}"
[[ "$url" == s3://* && -n "${rest%%/*}" ]] \
|| { echo "s3 URL missing bucket: $url"; exit 1; } Type guard
func hasBucketInS3URL(url string) bool {
if !strings.HasPrefix(url, "s3://") {
return false
}
rest := strings.TrimPrefix(url, "s3://")
bucket := rest
if i := strings.IndexByte(rest, '/'); i >= 0 {
bucket = rest[:i]
}
return bucket != ""
} Prevention
- Guard variables used to build s3:// URLs: use ${BUCKET:?message} so empty values fail fast
- Never hardcode placeholder 's3://' in CI templates for the state store; make the bucket a required input
- Echo/inspect KOPS_STATE_STORE when it comes from templated config before kops runs
- Keep bucket and prefix together in one validated variable instead of concatenating 's3://' at call sites
When it happens
Trigger: VFSPath receives a URL whose regex capture groups for 'bucket' and 'path' are both empty — e.g. 's3://', 's3:///', or a URL consisting only of scheme+separators — while converting a state-store specification via buildVFSPath. (Note: 's3://<path-only>' intentionally succeeds, returning s3:/<path>.)
Common situations: KOPS_STATE_STORE set to a placeholder 's3://' in CI/CD or docs copy-paste; a variable expansion that lost the bucket name (unset $BUCKET leaving 's3://'); scripts concatenating 's3://' with an empty variable; templating tools rendering empty config values.
Related errors
- %s is not a valid S3 URL
- error populating configuration: %v
- InstanceGroup name is missing
- ClusterName is missing
- host is empty
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b820e74ee9f239aa.
Report an issue: GitHub.