{"record":{"id":"8f115672941e6a70","repo":"juicedata/juicefs","slug":"unescape-secret-key-s","errorCode":null,"errorMessage":"unescape secret key: %s","messagePattern":"unescape secret key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/ks3.go","lineNumber":409,"sourceCode":"\tif strings.HasSuffix(uri.Host, \"ksyun.com\") || strings.HasSuffix(uri.Host, \"ksyuncs.com\") {\n\t\tregion = strings.TrimSuffix(region, \"-internal\")\n\t\tregion = ks3Regions[region]\n\t\tpathStyle = false\n\t} else if envRegion := os.Getenv(\"AWS_REGION\"); envRegion != \"\" {\n\t\tregion = envRegion\n\t}\n\tif region == \"\" {\n\t\tregion = \"us-east-1\"\n\t}\n\n\tvar err error\n\taccessKey, err = url.PathUnescape(accessKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unescape access key: %s\", err)\n\t}\n\tsecretKey, err = url.PathUnescape(secretKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unescape secret key: %s\", err)\n\t}\n\tawsConfig := &aws.Config{\n\t\tRegion:           region,\n\t\tEndpoint:         strings.SplitN(uri.Host, \".\", 2)[1],\n\t\tDisableSSL:       !ssl,\n\t\tHTTPClient:       httpClient,\n\t\tS3ForcePathStyle: pathStyle,\n\t\tCredentials:      credentials.NewStaticCredentials(accessKey, secretKey, token),\n\t}\n\n\treturn &ks3{bucket: bucket, s3: s3.New(awsConfig)}, nil\n}\n\nfunc init() {\n\tRegister(\"ks3\", newKS3)\n}\n","sourceCodeStart":391,"sourceCodeEnd":426,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/ks3.go#L391-L426","documentation":"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.","triggerScenarios":"Passing a secret key with an invalid escape (e.g. 'sec%ret' where '%re' is not valid hex) to newKS3.","commonSituations":"Secrets copied from URLs or config files where '%' characters were not encoded; shell or template expansion leaving raw '%' in the value.","solutions":["Fix or remove the malformed '%' sequence in the secret key.","Percent-encode literal '%' as %25 if the value must be URL-escaped.","Pass the secret via an environment variable or file rather than an escaped URL component."],"exampleFix":"// before\nsecretKey := \"sec%ret\"\n// after\nsecretKey := \"sec%25ret\" // decodes to \"sec%ret\"","handlingStrategy":"validation","validationCode":"if _, err := url.PathUnescape(secretKey); err != nil {\n\treturn fmt.Errorf(\"secret key is not valid percent-encoding: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := url.PathUnescape(secretKey); err != nil {\n\t// fall back to treating the value as raw\n\tsecretKey = strings.ReplaceAll(secretKey, \"%\", \"%25\")\n}","preventionTips":["Avoid hand-building escaped credential strings; use proper url.Values encoding.","Audit config files for bare '%' characters in secret values.","Prefer file-based or env-based credential delivery."],"tags":["object-storage","url-encoding","credentials"],"backgroundTag":"invalid-url-format","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}