{"record":{"id":"24dd709efa9771cc","repo":"lionsoul2014/ip2region","slug":"incomplete-read-rbytes-read-header-headerin","errorCode":null,"errorMessage":"incomplete read (${rBytes} read, ${header.HeaderInfoLength} expected)","messagePattern":"incomplete read \\((.+?) read, (.+?) expected\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"binding/javascript/util.js","lineNumber":342,"sourceCode":"    }\n\n    let ipVer = h.ipVersion;\n    if (ipVer == XdbIPv4Id) {\n        return IPv4;\n    } else if (ipVer == XdbIPv6Id) {\n        return IPv6;\n    } else {\n        return null;\n    }\n}\n\n// ---\n\nexport function loadHeader(fd) {\n    const buffer = Buffer.alloc(HeaderInfoLength);\n    const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);\n    if (rBytes != HeaderInfoLength) {\n        throw new Error(`incomplete read (${rBytes} read, ${header.HeaderInfoLength} expected)`);\n    }\n    return new Header(buffer);\n}\n\nexport function loadHeaderFromFile(dbPath) {\n    const fd = fs.openSync(dbPath, \"r\");\n    const header = loadHeader(fd);\n    fs.closeSync(fd);\n    return header;\n}\n\nexport function loadVectorIndex(fd) {\n    const vBytes = VectorIndexCols * VectorIndexRows * VectorIndexSize;\n    const buffer = Buffer.alloc(vBytes);\n    const rBytes = fs.readSync(fd, buffer, 0, vBytes, HeaderInfoLength);\n    if (rBytes != vBytes) {\n        throw new Error(`incomplete read (${rBytes} read, ${vBytes} expected)`);\n    }","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/lionsoul2014/ip2region/blob/c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1/binding/javascript/util.js#L324-L360","documentation":"loadHeader reads the fixed-size header block (HeaderInfoLength bytes) from offset 0 of an open xdb file descriptor. If fs.readSync returns fewer bytes than the header requires, the file is too small or truncated, and the library throws with the actual vs expected byte counts.","triggerScenarios":"Calling loadHeader(fd) / header() on a file shorter than HeaderInfoLength — an empty file, a partially downloaded/copied xdb, a wrong file passed in, or a fd already at EOF due to reuse assumptions (readSync here is positioned at 0, so mainly file size matters).","commonSituations":"Interrupted download or rsync of the .xdb data file; mounting a volume where the file was replaced mid-read; pointing the searcher at a config/log file by mistake.","solutions":["Re-download or re-copy the xdb data file and verify its size/checksum against the official release.","Confirm the path passed to loadHeaderFromFile/Searcher points at a genuine xdb v2/v3 data file (starts with the expected magic).","Check disk space and that the file finished writing (no in-progress producer).","Compare fs.fstatSync(fd).size with HeaderInfoLength before calling to fail fast with a clearer message."],"exampleFix":"// before\nconst header = loadHeader(fd); // throws on truncated file\n// after\nconst size = fs.fstatSync(fd).size;\nif (size < HeaderInfoLength) throw new Error(`${dbPath} truncated: ${size} bytes`);\nconst header = loadHeader(fd);","handlingStrategy":"validation","validationCode":"const fd = fs.openSync(dbPath, 'r');\nif (fs.fstatSync(fd).size < HeaderInfoLength)\n  throw new Error(`${dbPath} is ${fs.fstatSync(fd).size} bytes; not a valid xdb file`);","typeGuard":null,"tryCatchPattern":"try {\n  const header = loadHeaderFromFile(dbPath);\n} catch (e) {\n  if (String(e.message).includes('incomplete read')) {\n    throw new Error(`xdb file ${dbPath} is truncated; re-download it`);\n  }\n  throw e;\n}","preventionTips":["Verify file size/checksum after download before deploying xdb files.","Ensure copy/deploy jobs complete (no partial rsync artifacts).","Never point the searcher at non-xdb files; log the resolved path at startup."],"tags":["nodejs","file-io","truncated-file","xdb"],"backgroundTag":"incomplete-file-read","analyzedSha":"c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1","analyzedAt":"2026-09-02T16:58:39.988Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}