{"record":{"id":"c7105247ff575936","repo":"juicedata/juicefs","slug":"can-not-generate-different-endpoint-using-s","errorCode":null,"errorMessage":"can not generate different endpoint using %s","messagePattern":"can not generate different endpoint using (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/sharding.go","lineNumber":234,"sourceCode":"func (s *sharded) AbortUpload(ctx context.Context, key string, uploadID string) {\n\ts.pick(key).AbortUpload(ctx, key, uploadID)\n}\n\nfunc (s *sharded) CompleteUpload(ctx context.Context, key string, uploadID string, parts []*Part) error {\n\treturn s.pick(key).CompleteUpload(ctx, key, uploadID, parts)\n}\n\nfunc (s *sharded) Restore(ctx context.Context, key string, days int32) error {\n\treturn s.pick(key).Restore(ctx, key, days)\n}\n\nfunc NewSharded(name, endpoint, ak, sk, token string, shards int) (ObjectStorage, error) {\n\tstores := make([]ObjectStorage, shards)\n\tvar err error\n\tfor i := range stores {\n\t\tep := fmt.Sprintf(endpoint, i)\n\t\tif strings.HasSuffix(ep, \"%!(EXTRA int=0)\") {\n\t\t\treturn nil, fmt.Errorf(\"can not generate different endpoint using %s\", endpoint)\n\t\t}\n\t\tstores[i], err = CreateStorage(name, ep, ak, sk, token)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn &sharded{stores: stores}, nil\n}\n\nvar _ SupportTier = (*sharded)(nil)\nvar _ ObjectStorage = (*sharded)(nil)\n","sourceCodeStart":216,"sourceCodeEnd":246,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/sharding.go#L216-L246","documentation":"NewSharded builds N storage clients by formatting the endpoint template with the shard index (fmt.Sprintf(endpoint, i)). If the resulting endpoint still contains a leftover format artifact (the check detects the '%!(EXTRA int=0)' Sprintf output), the endpoint string was not a valid template with a %d verb, meaning all shards would get the same endpoint — which defeats sharding — so it fails fast.","triggerScenarios":"Calling NewSharded with an endpoint that contains no %d verb (e.g. 'http://shard.example.com' instead of 'http://shard%d.example.com'), or with extra arguments already baked in so Sprintf emits '%!(EXTRA int=0)'.","commonSituations":"Copy-pasting a normal single-endpoint config into the sharded storage type in JuiceFS's format/mount config; forgetting the %d placeholder when configuring sharded object storage.","solutions":["Add a %d verb to the endpoint, e.g. endpoint=\"http://shard%d.example.com\", so each shard gets a distinct address.","Ensure the endpoint string has no stray format verbs/arguments that leave EXTRA output; keep it a simple single-%d template.","If sharding is not desired, use the plain storage type instead of sharded."],"exampleFix":"// before\nCreateStorage(\"sharded\", \"http://shard.example.com\", ak, sk, \"\")\n// after (valid sharded endpoint template)\nNewSharded(\"sharded\", \"http://shard%d.example.com\", ak, sk, \"\", 4)","handlingStrategy":"validation","validationCode":"if !strings.Contains(endpoint, \"%d\") {\n    return fmt.Errorf(\"sharded endpoint must contain a %%d placeholder: %s\", endpoint)\n}","typeGuard":null,"tryCatchPattern":"store, err := object.NewSharded(name, endpoint, ak, sk, \"\", shards)\nif err != nil && strings.Contains(err.Error(), \"can not generate different endpoint\") {\n    return fmt.Errorf(\"endpoint %q lacks %%d placeholder for sharding\", endpoint)\n}","preventionTips":["Always include exactly one %d in sharded endpoint templates.","Validate the format string before storing it in config.","Test with a dry run (objbench) that all shard endpoints resolve to distinct hosts."],"tags":["config","endpoint","format-string"],"backgroundTag":"invalid-argument-format","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}