kubernetes/kops · error
invalid Linode object storage path: %q
Error message
invalid Linode object storage path: %q
What it means
buildLinodePath failed to parse the given path as a URL. Linode Object Storage locations must be parseable linode://bucket/key URLs; when url.Parse errors, the path is rejected with this message.
Source
Thrown at util/pkg/vfs/context.go:407
}
s3path := newS3Path(c.s3Context, u.Scheme, bucket, u.Path, false, func(o *s3.Options) {
o.BaseEndpoint = aws.String(endpoint)
o.UsePathStyle = true
o.DisableLogOutputChecksumValidationSkipped = true
})
return s3path, nil
}
func (c *VFSContext) buildLinodePath(p string) (*S3Path, error) {
endpoint := os.Getenv("S3_ENDPOINT")
if endpoint == "" {
return nil, fmt.Errorf("required S3_ENDPOINT env var for path: %q", p)
}
u, err := url.Parse(p)
if err != nil {
return nil, fmt.Errorf("invalid Linode object storage path: %q", p)
}
if u.Scheme != "linode" {
return nil, fmt.Errorf("invalid Linode object storage path: %q", p)
}
bucket := strings.TrimSuffix(u.Host, "/")
if bucket == "" {
return nil, fmt.Errorf("invalid Linode object storage path: %q", p)
}
s3path := newS3Path(c.s3Context, u.Scheme, bucket, u.Path, false, func(o *s3.Options) {
o.BaseEndpoint = aws.String(endpoint)
o.UsePathStyle = true
o.DisableLogOutputChecksumValidationSkipped = true
// Akamai (Linode) requires checksum-when-required behavior
o.RequestChecksumCalculation = aws.RequestChecksumCalculationWhenRequired
o.ResponseChecksumValidation = aws.ResponseChecksumValidationWhenRequired
})View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the quoted path in the error and remove or percent-encode invalid characters.
- Use url.PathEscape for dynamic bucket/key segments when composing the path.
- Set KOPS_STATE_STORE to a clean literal like linode://my-bucket/clusters.
Example fix
// before
statePath := fmt.Sprintf("linode://%s/state", taintedName)
// after
statePath := "linode://" + url.PathEscape(name) + "/state" Defensive patterns
Strategy: validation
Validate before calling
func validLinodeStorePath(p string) bool {
u, err := url.Parse(p)
return err == nil && u.Scheme == "linode" && strings.TrimSuffix(u.Host, "/") != ""
}
if !validLinodeStorePath(os.Getenv("KOPS_STATE_STORE")) {
return fmt.Errorf("KOPS_STATE_STORE must be a valid linode://bucket/path URL, got %q", os.Getenv("KOPS_STATE_STORE"))
} Type guard
func isParsableURL(p string) bool {
_, err := url.Parse(p)
return err == nil
} Try / catch
p, err := vfs.Context.BuildVfsPath(raw)
if err != nil {
if strings.Contains(err.Error(), "invalid Linode object storage path") {
return fmt.Errorf("malformed Linode path %q: %w", raw, err)
}
return err
} Prevention
- Set KOPS_STATE_STORE as a literal linode://bucket/path value.
- Percent-encode dynamic segments with url.PathEscape.
- Avoid interpolating raw/untrusted strings into the store path.
- Echo the path with %q to spot hidden control characters.
When it happens
Trigger: Calling BuildVfsPath with a linode:// string that url.Parse rejects — invalid percent-escapes (linode://bucket/%zz), control characters, or unescaped non-ASCII bytes in bucket/key.
Common situations: Store path assembled by templating that injects malformed characters; copy-paste artifacts in KOPS_STATE_STORE.
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
- error parsing ConfigStore.Base %q: %v
- error parsing locationStore=%q: %w
- parsing etcd backup-store %q: %w
- parsing configStore.base %q: %w
- cannot parse VFS path %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/2b71b2cce210d339.
Report an issue: GitHub.