juicedata/juicefs · critical

invalid dumped meta: missing 'Counters'

Error message

invalid dumped meta: missing 'Counters'

What it means

DumpedMeta.validate enforces that a dumped metadata image contains the 'Counters' section, which records essential global counters. Loading a dump without Counters would silently lose correctness-critical bookkeeping, so load/dump validation rejects it explicitly.

Source

Thrown at pkg/meta/dump.go:349

	return nil
}

type DumpedMeta struct {
	Setting     Format
	Counters    *DumpedCounters
	Sustained   []*DumpedSustained
	DelFiles    []*DumpedDelFile
	Quotas      map[Ino]*DumpedQuota    `json:",omitempty"`
	UserQuotas  map[uint64]*DumpedQuota `json:",omitempty"`
	GroupQuotas map[uint64]*DumpedQuota `json:",omitempty"`
	ChangeLog   []*DumpedChangeLog      `json:",omitempty"`
	FSTree      *DumpedEntry            `json:",omitempty"`
	Trash       *DumpedEntry            `json:",omitempty"`
}

func (dm *DumpedMeta) validate() error {
	if dm.Counters == nil {
		return errors.New("invalid dumped meta: missing 'Counters'")
	}
	return nil
}

func (dm *DumpedMeta) writeJsonWithOutTree(w io.Writer) (*bufio.Writer, error) {
	if dm.FSTree != nil || dm.Trash != nil {
		return nil, fmt.Errorf("invalid dumped meta")
	}
	data, err := json.MarshalIndent(dm, "", jsonIndent)
	if err != nil {
		return nil, err
	}
	bw := bufio.NewWriterSize(w, jsonWriteSize)
	if _, err = bw.Write(append(data[:len(data)-2], ',')); err != nil { // delete \n}
		return nil, err
	}
	return bw, nil
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Regenerate the dump from the live metadata engine with a current juicefs version so Counters is included.
  2. Restore Counters into the dump JSON from a complete backup before loading.
  3. Refuse to load the incomplete dump and use a full backup instead; verify the dump contains Counters before load (e.g. grep '"Counters"').

Example fix

// before (truncated dump)
{"Setting": {...}, "FSTree": {...}}
// after
{"Setting": {...}, "Counters": {"usedSpace": 0, "totalInodes": 1, ...}, "FSTree": {...}}
Defensive patterns

Strategy: validation

Validate before calling

func dumpHasCounters(path string) (bool, error) {
	f, err := os.Open(path); if err != nil { return false, err }
	defer f.Close()
	dec := json.NewDecoder(bufio.NewReader(f))
	for {
		tok, err := dec.Token(); if err == io.EOF { return false, nil }; if err != nil { return false, err }
		if k, ok := tok.(string); ok && k == "Counters" { return true, nil }
	}
}

Prevention

When it happens

Trigger: Loading (juicefs load or restore paths) a metadata dump file whose JSON lacks the "Counters" field, e.g. a hand-edited, truncated, or very old/incomplete dump.

Common situations: Restoring from a manually trimmed dump that removed what looked like optional fields; dumps produced by buggy/old tooling before Counters existed; truncated backup files.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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