juicedata/juicefs · error
tierID:%d not found for %s
Error message
tierID:%d not found for %s
What it means
In azure.go Copy(), when the request context carries a TierKey and src == dst, the code performs a SetTier operation on the blob instead of a copy. The target access tier is looked up in the configured b.tiers map by tier id; this error is returned when str2Tier cannot map the configured storage-class string to an azblob access tier, meaning the tier entry is invalid for Azure.
Source
Thrown at pkg/object/azure.go:136
parts := strings.SplitN(t.Tag, "=", 2)
options.Tags = map[string]string{parts[0]: parts[1]}
}
resp, err := b.azblobCli.UploadStream(ctx, b.cName, key, data, &options)
attrs := ApplyGetters(getters...)
attrs.SetRequestID(aws.ToString(resp.RequestID)).SetStorageClass(t.Sc)
return err
}
func (b *wasb) Copy(ctx context.Context, dst, src string) error {
// If a tier ID is provided in the context and the source and destination are the same,
// we interpret this as a request to change the storage class (tier) of the existing blob without copying.
// In this case, we call SetTier on the blob client instead of performing a copy operation.
if id, ok := ctx.Value(TierKey{}).(uint8); ok && src == dst {
blobClient := b.azblobCli.ServiceClient().NewContainerClient(b.cName).NewBlobClient(src)
if t, ok := b.tiers[id]; ok {
tier := str2Tier(t.Sc)
if tier == nil {
return fmt.Errorf("tierID:%d not found for %s", id, src)
}
if _, err := blobClient.SetTier(ctx, *tier, &blob2.SetTierOptions{}); err != nil {
return err
}
if t.Tag != "" && ValidateTag(t.Tag) {
parts := strings.SplitN(t.Tag, "=", 2)
if len(parts) == 2 {
if _, err := blobClient.SetTags(ctx, map[string]string{parts[0]: parts[1]}, nil); err != nil {
return err
}
}
}
} else {
return fmt.Errorf("invalid tier id: %d", id)
}
return nil
}
dstCli := b.container.NewBlobClient(dst)View on GitHub (pinned to c9a67b23e8)
Solutions
- Fix the storage class string for that tier id to a valid Azure access tier (Hot, Cool, Cold, Archive)
- Review the tiers configuration passed to newAzureBlob / the volume format --storage-class values
- Check str2Tier in pkg/object/azure.go for the accepted class names and align your config
- If the tier is intentionally unsupported, remove that tier id from the config rather than referencing it
Example fix
// before (S3-style class on Azure)
tiers: {2: {Sc: "STANDARD_IA"}}
// after
tiers: {2: {Sc: "Cool"}} Defensive patterns
Strategy: validation
Validate before calling
for id, t := range cfg.Tiers {
if str2Tier(t.Sc) == nil { return fmt.Errorf("tier %d has unsupported Azure class %q", id, t.Sc) }
} Prevention
- Use only Azure access tier names (Hot, Cool, Cold, Archive) for Azure backends
- Don't copy S3 storage-class configs onto Azure volumes
- Validate tier configs at volume format time
When it happens
Trigger: A write/context request sets a tier id whose b.tiers entry has a storage class string not recognized by str2Tier (e.g. an S3-style class like STANDARD_IA configured on an Azure backend).
Common situations: Configuring a JuiceFS volume's storage-class/tier list with class names copied from an S3 backend and reusing it against Azure Blob Storage; typo'd or localized tier names in the tiers config.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- invalid tier id: %d
- Invalid endpoint: %v, error: %v
- invalid hour number
- invalid unit
- cannot disable dir stats when there are still %d dir quotas:
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/03847c433bf69d6c.
Report an issue: GitHub.