juicedata/juicefs · error

inode %d slice %d : %w

Error message

inode %d slice %d : %w

What it means

When sliceIterator.Iterate runs a slice handler on a background goroutine (the concurrent channel path), any error the handler returns is captured into iter.err wrapped as "inode %d slice %d : %w". The error identifies which inode and which slice id failed, preserving the underlying cause via %w. It is reported after wg.Wait() as the return value of Iterate.

Source

Thrown at pkg/vfs/fill.go:466

			continue
		}
		var bytes uint64
		for _, p := range parts {
			bytes += uint64(p.Len)
		}
		atomic.AddUint64(&iter.stat.SliceCount, 1)
		atomic.AddUint64(&iter.stat.TotalBytes, bytes)

		select {
		case concurrent <- token{}:
			wg.Add(1)
			go func() {
				defer func() {
					<-concurrent
					wg.Done()
				}()
				if err := handler(s, parts); err != nil {
					iter.err = fmt.Errorf("inode %d slice %d : %w", iter.ino, s.Id, err)
				}
			}()
		default:
			if err := handler(s, parts); err != nil {
				iter.err = fmt.Errorf("inode %d slice %d : %w", iter.ino, s.Id, err)
			}
		}
	}
	wg.Wait()
	return iter.err
}

func newSliceIterator(ctx meta.Context, mClient meta.Meta, ino Ino, size uint64, stat *CacheResponse, ranges []ByteRange) *sliceIterator {
	return &sliceIterator{
		ctx:     ctx,
		mClient: mClient,
		ino:     ino,
		stat:    stat,

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Inspect the wrapped cause (%w) to find the real failure; fix that first.
  2. Verify object storage connectivity and credentials used by the chunk loader.
  3. Add per-slice error logging in your handler to pinpoint the failing part.
  4. Retry the iterate/fill operation; it only failed for one slice.

Example fix

// before
if err := handler(s, parts); err != nil {
    iter.err = fmt.Errorf("inode %d slice %d : %w", iter.ino, s.Id, err)
}
// after
if err := handler(s, parts); err != nil {
    iter.err = fmt.Errorf("inode %d slice %d : %w", iter.ino, s.Id, err)
    return // in handler: return err so caller can errors.As the root cause
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := iter.Iterate(handler, concurrent); err != nil {
    var cause error
    if errors.As(err, &cause) && cause != err {
        log.Printf("fill failed: %v (cause: %v)", err, cause)
    }
    // retry only the failed slice if handler is idempotent
}

Prevention

When it happens

Trigger: A sliceHandler invoked asynchronously by Iterate returns a non-nil error, e.g. the cache-fill handler fails to load or register slice parts for a given slice of the inode.

Common situations: Prefetch/cache-warm operations where the object store is unreachable or a block download fails while filling chunks for an inode; a handler closure capturing a resource (channel, store client) that has since been closed.

Related errors


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