thanos-io/thanos · error
failed to parse as JSON
Error message
failed to parse %s as JSON: %q
What it means
ReadMetaFile parses a shipper meta file (JSON) from disk and wraps any json.Unmarshal failure with this message, including the file path and raw content. It is thrown because the meta file bytes are not valid JSON (or not decodable into shipper.Meta), so the shipper cannot determine which blocks were uploaded.
Solutions
- Inspect the file contents (`cat <path>`) and fix or regenerate the corrupted meta.json.
- Delete the corrupt meta file and re-run the shipper Sync so it recreates meta state from the object store.
- Verify the process writing the meta file completes writes atomically (write to temp file then rename) to prevent truncation.
- Check disk health and available space if corruption recurs.
Example fix
// before
m, err := shipper.ReadMetaFile(path)
// after
if _, err := os.Stat(path); err != nil { return err }
b, _ := os.ReadFile(path)
if !json.Valid(b) {
// regenerate or restore meta file before parsing
return fmt.Errorf("meta file %s is not valid JSON", path)
}
m, err := shipper.ReadMetaFile(path) Defensive patterns
Strategy: validation
Validate before calling
b, err := os.ReadFile(path)
if err != nil { return err }
if !json.Valid(b) {
return fmt.Errorf("meta file %s is not valid JSON; regenerate or delete it", path)
} Try / catch
m, err := shipper.ReadMetaFile(path)
if err != nil {
var corrupted = strings.Contains(err.Error(), "as JSON")
if corrupted {
// delete/regenerate meta and retry
}
return err
} Prevention
- Write meta files atomically (temp file + rename).
- Never hand-edit meta.json while the shipper runs.
- Monitor disks for full/corrupt conditions.
- Back up meta files before upgrades.
When it happens
Trigger: Calling shipper.ReadMetaFile (directly or via Sync, AreAllBlocksUploaded, UploadedBlocks) when the meta.json file at `path` contains malformed JSON, empty bytes, or a structurally incompatible JSON document.
Common situations: Truncated meta file after a crash/power loss mid-write; manually edited meta.json with a typo; file written by an incompatible older/newer format; filesystem corruption; reading a directory or lock file by mistake instead of the meta file.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- meta.json corrupted
- first pass of downsampling failed
- input block index not valid
- read meta
- open data dir
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/06027571ba2d8ab4.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/shipper/shipper.go:658
if err := f.Sync(); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
return renameFile(logger, tmp, path)
}
// ReadMetaFile reads the given meta from <dir>/thanos.shipper.json.
func ReadMetaFile(path string) (*Meta, error) {
b, err := os.ReadFile(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to read %s", path)
}
var m Meta
if err := json.Unmarshal(b, &m); err != nil {
return nil, errors.Wrapf(err, "failed to parse %s as JSON: %q", path, string(b))
}
if m.Version != MetaVersion1 {
return nil, errors.Errorf("unexpected meta file version %d", m.Version)
}
return &m, nil
}
func renameFile(logger log.Logger, from, to string) error {
if err := os.RemoveAll(to); err != nil {
return err
}
if err := os.Rename(from, to); err != nil {
return err
}
// Directory was renamed; sync parent dir to persist rename.
pdir, err := fileutil.OpenDir(filepath.Dir(to))View on GitHub (pinned to 35b8b99117)