juicedata/juicefs · error

unescape secret key: %s

Error message

unescape secret key: %s

What it means

url.PathUnescape could not percent-decode the secret key for the KS3 backend. The secret key string contains malformed percent-encoding (e.g., a stray '%' or invalid hex pair), so credentials cannot be used for signing requests.

Source

Thrown at pkg/object/ks3.go:409

	if strings.HasSuffix(uri.Host, "ksyun.com") || strings.HasSuffix(uri.Host, "ksyuncs.com") {
		region = strings.TrimSuffix(region, "-internal")
		region = ks3Regions[region]
		pathStyle = false
	} else if envRegion := os.Getenv("AWS_REGION"); envRegion != "" {
		region = envRegion
	}
	if region == "" {
		region = "us-east-1"
	}

	var err error
	accessKey, err = url.PathUnescape(accessKey)
	if err != nil {
		return nil, fmt.Errorf("unescape access key: %s", err)
	}
	secretKey, err = url.PathUnescape(secretKey)
	if err != nil {
		return nil, fmt.Errorf("unescape secret key: %s", err)
	}
	awsConfig := &aws.Config{
		Region:           region,
		Endpoint:         strings.SplitN(uri.Host, ".", 2)[1],
		DisableSSL:       !ssl,
		HTTPClient:       httpClient,
		S3ForcePathStyle: pathStyle,
		Credentials:      credentials.NewStaticCredentials(accessKey, secretKey, token),
	}

	return &ks3{bucket: bucket, s3: s3.New(awsConfig)}, nil
}

func init() {
	Register("ks3", newKS3)
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Fix or remove the malformed '%' sequence in the secret key.
  2. Percent-encode literal '%' as %25 if the value must be URL-escaped.
  3. Pass the secret via an environment variable or file rather than an escaped URL component.

Example fix

// before
secretKey := "sec%ret"
// after
secretKey := "sec%25ret" // decodes to "sec%ret"
Defensive patterns

Strategy: validation

Validate before calling

if _, err := url.PathUnescape(secretKey); err != nil {
	return fmt.Errorf("secret key is not valid percent-encoding: %w", err)
}

Try / catch

if _, err := url.PathUnescape(secretKey); err != nil {
	// fall back to treating the value as raw
	secretKey = strings.ReplaceAll(secretKey, "%", "%25")
}

Prevention

When it happens

Trigger: Passing a secret key with an invalid escape (e.g. 'sec%ret' where '%re' is not valid hex) to newKS3.

Common situations: Secrets copied from URLs or config files where '%' characters were not encoded; shell or template expansion leaving raw '%' in the value.

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/8f115672941e6a70. Report an issue: GitHub.