{"record":{"id":"b112664a9f517744","repo":"kubernetes/kops","slug":"s-is-not-a-valid-s3-url","errorCode":null,"errorMessage":"%s is not a valid S3 URL","messagePattern":"(.+?) is not a valid S3 URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/s3context.go","lineNumber":364,"sourceCode":"\n\tconfig, err := awsconfig.LoadDefaultConfig(ctx, awsconfig.WithHTTPClient(shortTimeout))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to load AWS config: %w\", err)\n\t}\n\n\tclient := imds.NewFromConfig(config)\n\n\tmetadataRegion, err := client.GetRegion(ctx, &imds.GetRegionInput{})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting AWS region from metadata: %w\", err)\n\t}\n\n\treturn metadataRegion.Region, nil\n}\n\nfunc VFSPath(url string) (string, error) {\n\tif !s3UrlRegexp.MatchString(url) {\n\t\treturn \"\", fmt.Errorf(\"%s is not a valid S3 URL\", url)\n\t}\n\tgroupNames := s3UrlRegexp.SubexpNames()\n\tresult := s3UrlRegexp.FindAllStringSubmatch(url, -1)[0]\n\n\tcaptured := map[string]string{}\n\tfor i, value := range result {\n\t\tif value != \"\" {\n\t\t\tcaptured[groupNames[i]] = value\n\t\t}\n\t}\n\tbucket := captured[\"bucket\"]\n\tpath := captured[\"path\"]\n\tif bucket == \"\" {\n\t\tif path == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"%s is not a valid S3 URL. No bucket defined.\", url)\n\t\t}\n\t\treturn fmt.Sprintf(\"s3:/%s\", path), nil\n\t}","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/s3context.go#L346-L382","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nexport KOPS_STATE_STORE=my-kops-state\nkops create cluster ...\n// error: my-kops-state is not a valid S3 URL\n// after\nexport KOPS_STATE_STORE=s3://my-kops-state","handlingStrategy":"validation","validationCode":"// Validate the state-store URL shape before invoking kops\n[[ \"$KOPS_STATE_STORE\" =~ ^s3://[a-z0-9][a-z0-9.-]{2,62} ]] \\\n  || { echo \"KOPS_STATE_STORE must be s3://<bucket>[/<prefix>], got: $KOPS_STATE_STORE\"; exit 1; }","typeGuard":"func isValidS3URL(url string) bool {\n\treturn strings.HasPrefix(url, \"s3://\") && len(url) > len(\"s3://\")\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["validation","s3","url-parsing","configuration"],"backgroundTag":"invalid-s3-url","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}