kopia/kopia · error

invalid kind for stats

Error message

invalid kind for stats %v

What it means

BuildFromExtra switches on the persisted stats Kind and wraps ErrUnSupportedStatKindError with "invalid kind for stats %v" when the kind is not one of the known stats kinds (e.g. cleanup-logs, rewrite-contents, snapshot-gc). It means the Extra blob cannot be decoded because its kind is unrecognized by this build of the library.

Solutions

  1. Check errors.Is(err, ErrUnSupportedStatKindError) and skip/ignore stats of unknown kinds instead of failing the whole run.
  2. Upgrade the binary to a version that supports the stored stats kind.
  3. Verify the Kind string stored in Extra against the supported kinds in maintenancestats/builder.go.
  4. Re-create or discard the corrupted run record.

Example fix

// before
msg, err := BuildFromExtra(ctx, run.Extra)
if err != nil { return err }
// after
msg, err := BuildFromExtra(ctx, run.Extra)
if errors.Is(err, ErrUnSupportedStatKindError) {
    return nil // skip unknown stats kinds (e.g. from a newer version)
}
Defensive patterns

Strategy: fallback

Validate before calling

// check kind support before decoding:
supported := map[string]bool{"cleanup-logs": true, "rewrite-contents": true, "snapshot-gc": true}
if !supported[run.Extra.Kind] { log.Warnf("unknown stats kind %q, skipping", run.Extra.Kind) }

Type guard

func hasSupportedStatsKind(k string) bool {
    switch k {
    case "cleanup-logs", "rewrite-contents", "snapshot-gc":
        return true
    }
    return false
}

Try / catch

msg, err := BuildFromExtra(ctx, run.Extra)
if errors.Is(err, ErrUnSupportedStatKindError) {
    log.Warnf("stats kind %q not supported by this version; skipping", run.Extra.Kind)
    return nil
}

Prevention

When it happens

Trigger: Calling BuildFromExtra with a Run.Extra whose Kind was produced by a newer/older kopia version with a stats kind this binary does not know, or a corrupted/overwritten Extra record.

Common situations: Reading maintenance history written by a newer Kopia release after downgrading the binary; manual edits or migration bugs corrupting the stored Kind; custom stats kinds not registered.

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 kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/d1cb08d226dedc98. Report an issue: GitHub.

Appendix: source

Thrown at repo/maintenancestats/builder.go:74

		result = &GenerateRangeCheckpointStats{}
	case advanceEpochStatsKind:
		result = &AdvanceEpochStats{}
	case compactSingleEpochStatsKind:
		result = &CompactSingleEpochStats{}
	case compactIndexesStatsKind:
		result = &CompactIndexesStats{}
	case deleteUnreferencedPacksStatsKind:
		result = &DeleteUnreferencedPacksStats{}
	case extendBlobRetentionStatsKind:
		result = &ExtendBlobRetentionStats{}
	case cleanupLogsStatsKind:
		result = &CleanupLogsStats{}
	case rewriteContentsStatsKind:
		result = &RewriteContentsStats{}
	case snapshotGCStatsKind:
		result = &SnapshotGCStats{}
	default:
		return nil, errors.Wrapf(ErrUnSupportedStatKindError, "invalid kind for stats %v", stats)
	}

	if err := json.Unmarshal(stats.Data, result); err != nil {
		return nil, errors.Wrapf(err, "error unmarshaling raw stats %v of kind %s to %T", stats.Data, stats.Kind, result)
	}

	return result, nil
}

View on GitHub (pinned to 82495e54b5)