{"record":{"id":"0eea47b1cc9be0b5","repo":"lionsoul2014/ip2region","slug":"incomplete-read-readed-bytes-should-be-d-0eea47","errorCode":null,"errorMessage":"incomplete read: readed bytes should be %d","messagePattern":"incomplete read: readed bytes should be (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"binding/golang/xdb/util.go","lineNumber":201,"sourceCode":"\n\treturn Verify(handle)\n}\n\n// LoadHeader load the header info from the specified handle\nfunc LoadHeader(handle io.ReadSeeker) (*Header, error) {\n\t_, err := handle.Seek(0, 0)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"seek to the header: %w\", err)\n\t}\n\n\tvar buff = make([]byte, HeaderInfoLength)\n\trLen, err := handle.Read(buff)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif rLen != len(buff) {\n\t\treturn nil, fmt.Errorf(\"incomplete read: readed bytes should be %d\", len(buff))\n\t}\n\n\treturn NewHeader(buff)\n}\n\n// LoadHeaderFromFile load header info from the specified db file path\nfunc LoadHeaderFromFile(dbFile string) (*Header, error) {\n\thandle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"open xdb file `%s`: %w\", dbFile, err)\n\t}\n\tdefer handle.Close()\n\n\theader, err := LoadHeader(handle)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/lionsoul2014/ip2region/blob/c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1/binding/golang/xdb/util.go#L183-L219","documentation":"After seeking to 0, LoadHeader reads HeaderInfoLength (256) bytes into a buffer. If the reader returned fewer bytes than the buffer length (rLen != len(buff)), the header is truncated/short and this error is thrown. It guarantees the caller never gets a partially filled Header.","triggerScenarios":"Calling LoadHeader on a file/reader shorter than 256 bytes, or a reader that returns a short read at EOF — e.g. an empty or truncated .xdb file, or a bytes.Reader constructed from a partial header buffer.","commonSituations":"Incomplete download of the ip2region.xdb file; a zero-byte file created by a failed generator run; passing a buffer holding only part of the xdb to LoadHeader instead of LoadHeaderFromBuff.","solutions":["Re-download or regenerate the .xdb file — verify it is complete (e.g. compare file size or checksum with the publisher).","Check file size with os.Stat before calling; it must be at least HeaderInfoLength (256) bytes.","Use LoadHeaderFromBuff only when you genuinely hold a full header buffer, and never truncate the file first."],"exampleFix":"// before\nheader, err := xdb.LoadHeader(f) // f points at a truncated file\n// after\nfi, _ := f.Stat()\nif fi.Size() < int64(xdb.HeaderInfoLength) {\n    return fmt.Errorf(\"xdb file too small: %d bytes\", fi.Size())\n}\nheader, err := xdb.LoadHeader(f)","handlingStrategy":"validation","validationCode":"fi, err := os.Stat(dbFile)\nif err != nil { return err }\nif fi.Size() < int64(xdb.HeaderInfoLength) {\n    return fmt.Errorf(\"xdb file too small: %d bytes\", fi.Size())\n}","typeGuard":"func hasCompleteHeader(buf []byte) bool {\n    return len(buf) >= xdb.HeaderInfoLength\n}","tryCatchPattern":"header, err := xdb.LoadHeader(handle)\nif err != nil {\n    if strings.Contains(err.Error(), \"incomplete read\") {\n        return fmt.Errorf(\"xdb file is truncated; re-download it\")\n    }\n    return err\n}","preventionTips":["Verify file size/checksum after downloading the xdb","Run xdb.Verify at startup to detect truncated files early","Never truncate or partially copy the xdb during deployment"],"tags":["golang","io","short-read","truncated-file","xdb"],"backgroundTag":"incomplete-read-short-file","analyzedSha":"c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1","analyzedAt":"2026-09-02T16:58:39.988Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}