{"record":{"id":"0f19c39853f656aa","repo":"thanos-io/thanos","slug":"scanning-file-s","errorCode":null,"errorMessage":"scanning file %s","messagePattern":"scanning file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/local.go","lineNumber":107,"sourceCode":"\t\tif series == nil {\n\t\t\tlevel.Warn(logger).Log(\"msg\", \"not a valid series\", \"frame\", resp.String())\n\t\t\tcontinue\n\t\t}\n\t\tchks := make([]int, 0, len(series.Chunks))\n\t\t// Sort chunks in separate slice by MinTime for easier lookup. Find global max and min.\n\t\tfor ci := range series.Chunks {\n\t\t\tchks = append(chks, ci)\n\t\t}\n\n\t\tsort.Slice(chks, func(i, j int) bool {\n\t\t\treturn series.Chunks[chks[i]].MinTime < series.Chunks[chks[j]].MinTime\n\t\t})\n\t\ts.series = append(s.series, series)\n\t\ts.sortedChunks = append(s.sortedChunks, chks)\n\t}\n\n\tif err := skanner.Err(); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"scanning file %s\", path)\n\t}\n\tlevel.Info(logger).Log(\"msg\", \"loading JSON file succeeded\", \"file\", path, \"series\", len(s.series))\n\treturn s, nil\n}\n\n// ScanGRPCCurlProtoStreamMessages allows to tokenize each streamed gRPC message from grpcurl tool.\nfunc ScanGRPCCurlProtoStreamMessages(data []byte, atEOF bool) (advance int, token []byte, err error) {\n\tvar delim = []byte(`}\n{`)\n\tif atEOF && len(data) == 0 {\n\t\treturn 0, nil, nil\n\t}\n\tif idx := bytes.LastIndex(data, delim); idx != -1 {\n\t\treturn idx + 2, data[:idx+1], nil\n\t}\n\t// If we're at EOF, let's return all.\n\tif atEOF {\n\t\treturn len(data), data, nil","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/local.go#L89-L125","documentation":"After scanning all frames, NewLocalStoreFromJSONMmappableFile checks skanner.Err() and wraps any scanner-level I/O failure with \"scanning file <path>\". This is a low-level read error on the backing file, not a JSON schema issue.","triggerScenarios":"The mappable file is unreadable mid-scan: disk I/O error, permission change after open, or the file being truncated/deleted while scanning.","commonSituations":"Files on flaky network mounts (NFS/EFS); permission issues after container restarts; files deleted by cleanup jobs while being loaded.","solutions":["Check file permissions and that the path exists and is readable by the process.","Verify disk health / mount stability for the backing storage.","Regenerate the local store file if it was truncated or corrupted.","Inspect the wrapped inner error for the exact OS-level cause."],"exampleFix":"// before\nstore, err := NewLocalStoreFromJSONMmappableFile(mmappablePath)\n// after\nif _, err := os.Stat(mmappablePath); err != nil {\n  // regenerate dump first\n}\nstore, err := NewLocalStoreFromJSONMmappableFile(mmappablePath)","handlingStrategy":"try-catch","validationCode":"f, err := os.Open(path)\nif err != nil { return err }\nif fi, err := f.Stat(); err != nil || fi.Size() == 0 { return errors.New(\"missing or empty file\") }","typeGuard":null,"tryCatchPattern":"if err != nil {\n  if os.IsPermission(errors.Unwrap(err)) { /* fix perms */ }\n  // else regenerate the file and retry load\n}","preventionTips":["Keep dump files on stable local storage, not flaky network mounts","Ensure file permissions survive container restarts","Guard cleanup jobs against deleting in-use files"],"tags":["go","io","file"],"backgroundTag":"file-read-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}