{"record":{"id":"9f7cd9b4ea541501","repo":"lionsoul2014/ip2region","slug":"failed-to-fseek-to-offset","errorCode":null,"errorMessage":"failed to fseek to {$offset}","messagePattern":"failed to fseek to (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"binding/php/xdb/Searcher.class.php","lineNumber":557,"sourceCode":"        if ($dataLen == 0) {\n            return \"\";\n        }\n\n        // load and return the region data\n        return $this->read($dataPtr, $dataLen);\n    }\n\n    // read specified bytes from the specified index\n    private function read($offset, $len) {\n        // check the in-memory buffer first\n        if ($this->contentBuff != null) {\n            return substr($this->contentBuff, $offset, $len);\n        }\n\n        // read from the file\n        $r = fseek($this->handle, $offset);\n        if ($r == -1) {\n            throw new Exception(\"failed to fseek to {$offset}\");\n        }\n\n        $this->ioCount++;\n        $buff = fread($this->handle, $len);\n        if ($buff === false) {\n            throw new Exception(\"failed to fread from {$len}\");\n        }\n\n        if (strlen($buff) != $len) {\n            throw new Exception(\"incomplete read: read bytes should be {$len}\");\n        }\n\n        return $buff;\n    }\n\n}\n","sourceCodeStart":539,"sourceCodeEnd":574,"githubUrl":"https://github.com/lionsoul2014/ip2region/blob/c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1/binding/php/xdb/Searcher.class.php#L539-L574","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Recreate the Searcher via Searcher::newWithFileOnly() (or load the file into a buffer with newWithBuffer()) to get a fresh, valid handle","Confirm the xdb file path is correct and the file is not truncated or corrupted","Avoid sharing/closing the underlying file handle while searching; if resource limits are an issue use the buffered or vector-index load modes"],"exampleFix":"// before\n$searcher = new Searcher($dbFile, $header, $handle); // stale/closed handle\n// after\n$searcher = \\ip2region\\XdbSearcher::newWithFileOnly($dbFile);","handlingStrategy":"retry","validationCode":"if (!is_resource($searcher->getHandle()) || ftell($searcher->getHandle()) === false) {\n    $searcher = Searcher::newWithFileOnly($dbFile);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $region = $searcher->search($ip);\n} catch (\\Exception $e) {\n    if (strpos($e->getMessage(), 'failed to fseek') !== false) {\n        $searcher = Searcher::newWithFileOnly($dbFile); // rebuild handle, retry once\n        $region = $searcher->search($ip);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Never close or rewind the xdb file handle while the searcher is alive","Prefer newWithBuffer()/vector-index mode to minimize runtime seeks","Recreate the searcher per long-lived process instead of sharing one across requests that manage handles"],"tags":["php","file-io","seek","fseek"],"backgroundTag":"file-seek-failed","analyzedSha":"c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1","analyzedAt":"2026-09-02T16:58:39.988Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}