thanos-io/thanos · error
read convertedFromBLIDs field from parquet metadata file
Error message
read convertedFromBLIDs field from parquet metadata file: %v
What it means
Returned when field 6 (convertedFromBLIDs) of the parquet metadata protobuf message is present but fc.String() returns !ok — i.e. the field's wire type is not a string/bytes field as expected. Note the code wraps the (usually nil) err, so the wrap message carries the path but no underlying cause.
Solutions
- Regenerate the parquet metadata with a matching converter version
- Check whether the converter's proto definition changed field 6's type; align reader/writer versions
- Delete the offending metadata file if it is unrecoverable
Defensive patterns
Strategy: type-guard
Type guard
func isStringField(fc *easyproto.FieldContext) bool {
return fc.FieldNum == 6 && fc.String() != nil
} Try / catch
u, ok := fc.String()
if !ok { return fmt.Errorf("field 6 of %s is not a string", path) } Prevention
- Pin converter and reader to compatible versions
- Regenerate metadata after proto schema changes
- Validate written files with a round-trip decode test
- Never hand-edit parquet metadata files
When it happens
Trigger: A parquet metadata file whose field 6 is encoded with an unexpected wire type (varint/fixed instead of length-delimited) — produced by a schema mismatch or a corrupt/truncated file.
Common situations: Parquet converter version writing a different proto schema for field 6; manually edited or corrupted metadata files.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- read next field from parquet metadata file
- failed to convert matchers
- invalid duration
- bad cached type
- error marshaling proto response
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/93eb12a0f2eb4076.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/fetcher.go:1250
}
defer runutil.CloseWithLogOnErr(f.logger, r, "close bkt get")
content, err := io.ReadAll(r)
if err != nil {
return nil, errors.Wrapf(err, "read parquet metadata file: %v", path)
}
var fc easyproto.FieldContext
for len(content) > 0 {
content, err = fc.NextField(content)
if err != nil {
return nil, errors.Wrapf(err, "read next field from parquet metadata file: %v", path)
}
switch fc.FieldNum {
case 6:
u, ok := fc.String()
if !ok {
return nil, errors.Wrapf(err, "read convertedFromBLIDs field from parquet metadata file: %v", path)
}
id, err := ulid.Parse(u)
if err != nil {
return nil, errors.Wrapf(err, "parse block ID %q from parquet metadata file: %v", u, path)
}
migratedBlocks[id] = struct{}{}
}
}
return migratedBlocks, nil
}
// IgnoreDeletionMarkFilter is a filter that filters out the blocks that are marked for deletion after a given delay.
// The delay duration is to make sure that the replacement block can be fetched before we filter out the old block.
// Delay is not considered when computing DeletionMarkBlocks map.
// Not go-routine safe.
type IgnoreDeletionMarkFilter struct {
logger log.LoggerView on GitHub (pinned to 35b8b99117)