kubernetes/kops · error

invalid Hetzner Object Storage path: %q

Error message

invalid Hetzner Object Storage path: %q

What it means

When parsing a Hetzner Object Storage VFS path, buildHetznerPath expects a URL it can parse and whose scheme is "hos". If url.Parse itself fails on the raw string, kOps throws this variant (with capital-O "Object Storage") to signal the path is not a parseable URL at all, before any scheme check happens.

Source

Thrown at util/pkg/vfs/context.go:437

		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
	})
	return s3path, nil
}

func (c *VFSContext) buildHetznerPath(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 Hetzner Object Storage path: %q", p)
	}
	if u.Scheme != "hos" {
		return nil, fmt.Errorf("invalid Hetzner object storage path: %q", p)
	}

	bucket := strings.TrimSuffix(u.Host, "/")
	if bucket == "" {
		return nil, fmt.Errorf("invalid Hetzner 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
	})
	return s3path, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Print the exact state store value being passed and re-check for stray characters or whitespace
  2. Rewrite the path in the canonical form hos://<bucket>/<key>
  3. Quote the flag in the shell so shell metacharacters don't corrupt it: --state-store="hos://my-bucket"
  4. Check any script/env interpolation that builds the state store string for accidental truncation

Example fix

// before (unparseable)
--state-store=hos://my bucket
// after
--state-store="hos://my-bucket"
Defensive patterns

Strategy: validation

Validate before calling

if _, err := url.Parse(stateStore); err != nil {
	return fmt.Errorf("state store %q is not a valid URL: %w", stateStore, err)
}

Try / catch

p, err := vfs.Context.BuildVfsPath(stateStore)
if err != nil {
	if strings.Contains(err.Error(), "invalid Hetzner Object Storage path") {
		return fmt.Errorf("state store %q failed URL parsing; use hos://<bucket>", stateStore)
	}
	return err
}

Prevention

When it happens

Trigger: BuildVfsPath dispatches to buildHetznerPath (after S3_ENDPOINT is set) and url.Parse(p) returns a non-nil error for the given path string.

Common situations: State-store strings containing characters url.Parse rejects or misinterprets (unescaped spaces, control characters, stray colons like hos://:bucket); a mangled flag value pasted from docs or a script; a shell variable expansion that produced an empty or corrupted URL.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/2d99fef86c730987. Report an issue: GitHub.