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

  1. Fix the storage class string for that tier id to a valid Azure access tier (Hot, Cool, Cold, Archive)
  2. Review the tiers configuration passed to newAzureBlob / the volume format --storage-class values
  3. Check str2Tier in pkg/object/azure.go for the accepted class names and align your config
  4. 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

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


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