thanos-io/thanos · error

unexpected no-compact-mark file version

Error message

unexpected no-compact-mark file version %d, expected %d

What it means

After unmarshaling a no-compact-mark file, ReadMarker verifies that the Version field equals NoCompactMarkVersion1. This error is raised when the marker file exists and parses, but its version number is not the supported version 1, meaning the marker was written by a different (newer or older) format than this binary understands.

Solutions

  1. Check the Version field in the no-compact-mark file and confirm which M3DB version wrote it.
  2. Upgrade (or align) the binary reading the marker to the version that wrote it so the formats match.
  3. If the marker is stale/safe to drop, remove the no-compact-mark file and let compaction resume; re-create it with the current tooling if needed.
  4. Verify cluster-wide that all nodes run a version supporting the same marker version (version 1).

Example fix

// before: old binary reading a newer marker fails
// no-compact-mark contains {"Version": 2}

// after: upgrade binary, or rewrite the marker with supported version
deleteNoCompactMark(namespace, blockID)
WriteMarker(nsMd, blockID, &NoCompactMark{Version: NoCompactMarkVersion1})
Defensive patterns

Strategy: validation

Validate before calling

var m struct{ Version int `json:"version"` }
if json.Unmarshal(data, &m) == nil && m.Version != metadata.NoCompactMarkVersion1 {
    // reject/invalidate the marker before calling ReadMarker
}

Type guard

func isKnownNoCompactVersion(v int) bool { return v == metadata.NoCompactMarkVersion1 }

Try / catch

if err := metadata.ReadMarker(path, marker); err != nil {
    if strings.Contains(err.Error(), "unexpected no-compact-mark file version") {
        // version skew: stop, align binary versions, do not auto-delete
        return fmt.Errorf("marker version skew: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ReadMarker on a no-compact-mark file whose JSON contains a Version field with a value other than NoCompactMarkVersion1 — e.g. a file written by a newer M3DB release with version 2, or a hand-edited file with version 0 or a garbage value.

Common situations: Rolling upgrade/downgrade: a marker written by a newer node is read by an older binary; an operator manually edited the version field; a malformed writer bug emitted version 0.

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 thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/b90a61597668681c. Report an issue: GitHub.

Appendix: source

Thrown at pkg/block/metadata/markers.go:141

		if bkt.IsObjNotFoundErr(err) {
			return ErrorMarkerNotFound
		}
		return errors.Wrapf(err, "get file: %s", markerFile)
	}
	defer runutil.CloseWithLogOnErr(logger, r, "close bkt marker reader")

	metaContent, err := io.ReadAll(r)
	if err != nil {
		return errors.Wrapf(err, "read file: %s", markerFile)
	}

	if err := json.Unmarshal(metaContent, marker); err != nil {
		return errors.Wrapf(ErrorUnmarshalMarker, "file: %s; err: %v", markerFile, err.Error())
	}
	switch marker.markerFilename() {
	case NoCompactMarkFilename:
		if version := marker.(*NoCompactMark).Version; version != NoCompactMarkVersion1 {
			return errors.Errorf("unexpected no-compact-mark file version %d, expected %d", version, NoCompactMarkVersion1)
		}
	case NoDownsampleMarkFilename:
		if version := marker.(*NoDownsampleMark).Version; version != NoDownsampleMarkVersion1 {
			return errors.Errorf("unexpected no-downsample-mark file version %d, expected %d", version, NoDownsampleMarkVersion1)
		}
	case DeletionMarkFilename:
		if version := marker.(*DeletionMark).Version; version != DeletionMarkVersion1 {
			return errors.Errorf("unexpected deletion-mark file version %d, expected %d", version, DeletionMarkVersion1)
		}
	}
	return nil
}

View on GitHub (pinned to 35b8b99117)