lionsoul2014/ip2region · error · Exception

failed to fseek to {$offset}

Error message

failed to fseek to {$offset}

What it means

During a file-based (non-full-buffer) search, the searcher repositions the file handle with fseek() to the computed offset. A return of -1 means the seek failed, so the library cannot read the index/data block and aborts the search.

Source

Thrown at binding/php/xdb/Searcher.class.php:557

        if ($dataLen == 0) {
            return "";
        }

        // load and return the region data
        return $this->read($dataPtr, $dataLen);
    }

    // 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

  1. Recreate the Searcher via Searcher::newWithFileOnly() (or load the file into a buffer with newWithBuffer()) to get a fresh, valid handle
  2. Confirm the xdb file path is correct and the file is not truncated or corrupted
  3. Avoid sharing/closing the underlying file handle while searching; if resource limits are an issue use the buffered or vector-index load modes

Example fix

// before
$searcher = new Searcher($dbFile, $header, $handle); // stale/closed handle
// after
$searcher = \ip2region\XdbSearcher::newWithFileOnly($dbFile);
Defensive patterns

Strategy: retry

Validate before calling

if (!is_resource($searcher->getHandle()) || ftell($searcher->getHandle()) === false) {
    $searcher = Searcher::newWithFileOnly($dbFile);
}

Try / catch

try {
    $region = $searcher->search($ip);
} catch (\Exception $e) {
    if (strpos($e->getMessage(), 'failed to fseek') !== false) {
        $searcher = Searcher::newWithFileOnly($dbFile); // rebuild handle, retry once
        $region = $searcher->search($ip);
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling search() with a file handle whose fseek() to the internal offset returns -1 — typically an invalid/closed handle, or an offset beyond what the handle supports.

Common situations: The xdb file was closed or reopened elsewhere mid-search; passing the wrong resource type or a handle opened in a mode that disallows seeking; corrupted xdb producing out-of-range offsets.

Related errors


AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02). Data as JSON: /api/errors/9f7cd9b4ea541501. Report an issue: GitHub.