lionsoul2014/ip2region · error · Exception
failed to fread from {$len}
Error message
failed to fread from {$len} What it means
After a successful fseek, the searcher reads $len bytes with fread(); fread() returning false means the read itself failed at the OS/PHP level. The library throws to signal that the xdb index could not be read.
Source
Thrown at binding/php/xdb/Searcher.class.php:563
}
// read specified bytes from the specified index
private function read($offset, $len) {
// check the in-memory buffer first
if ($this->contentBuff != null) {
return substr($this->contentBuff, $offset, $len);
}
// read from the file
$r = fseek($this->handle, $offset);
if ($r == -1) {
throw new Exception("failed to fseek to {$offset}");
}
$this->ioCount++;
$buff = fread($this->handle, $len);
if ($buff === false) {
throw new Exception("failed to fread from {$len}");
}
if (strlen($buff) != $len) {
throw new Exception("incomplete read: read bytes should be {$len}");
}
return $buff;
}
}
View on GitHub (pinned to c1a1fc7d59)
Solutions
- Re-create the searcher (newWithFileOnly or newWithBuffer) so a fresh, readable handle is used
- Check file permissions and that the xdb file still exists and is readable by the PHP process
- Use newWithBuffer()/full-buffer mode to read the whole file once and avoid repeated I/O failures during search
Example fix
// before $handle = fopen($dbFile, 'rb'); // unreadable perms // after $searcher = \ip2region\XdbSearcher::newWithBuffer(file_get_contents($dbFile));
Defensive patterns
Strategy: try-catch
Validate before calling
if (!is_readable($dbFile)) {
throw new RuntimeException("xdb file not readable: {$dbFile}");
} Try / catch
try {
$region = $searcher->search($ip);
} catch (\Exception $e) {
if (strpos($e->getMessage(), 'failed to fread') !== false) {
$region = null; // log and mark service degraded / reload searcher
} else {
throw $e;
}
} Prevention
- Verify file readability and permissions at startup
- Load the xdb fully into memory (buffer mode) for high-traffic services
- Watch for external processes replacing/deleting the xdb file and reload on change
When it happens
Trigger: search()/read() on a file-backed searcher where fread() returns false — closed or unreadable handle, disk/permission error, or stream in an error state.
Common situations: File deleted or permissions changed after the searcher was created; reading from a network mount that dropped; handle exhausted by an earlier error.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to fseek to {$offset}
- incomplete read: read bytes should be {$len}
- incomplete read (${rBytes} read, ${header.HeaderInfoLength}
- incomplete read (${rBytes} read, ${vBytes} expected)
- incomplete read (${rBytes} read, ${stats.size} expected)
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/47acaf936929a8d8.
Report an issue: GitHub.