{"record":{"id":"ed66f72171bcb78e","repo":"stride3d/stride","slug":"cannot-seek-to-the-specified-position","errorCode":null,"errorMessage":"Cannot seek to the specified position.","messagePattern":"Cannot seek to the specified position\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.IO/VirtualFileStream.cs","lineNumber":192,"sourceCode":"                break;\n            case SeekOrigin.End:\n                // Maybe we don't know the actual file size (full file)\n                if (endPosition == -1)\n                {\n                    InternalStream.Seek(offset, SeekOrigin.End);\n                }\n                else\n                {\n                    InternalStream.Seek(endPosition - startPosition + offset, SeekOrigin.Begin);\n                }\n                break;\n        }\n\n        var newPosition = InternalStream.Position;\n        if (newPosition < startPosition || (endPosition != -1 && newPosition > endPosition))\n        {\n            InternalStream.Position = startPosition;\n            throw new IOException(\"Cannot seek to the specified position.\");\n        }\n\n        return newPosition;\n    }\n\n    /// <inheritdoc/>\n    public override void SetLength(long value)\n    {\n        if (endPosition != -1)\n        {\n            throw new NotSupportedException(\"Can't resize VirtualFileStream if endPosition is not -1.\");\n        }\n\n        InternalStream.SetLength(value);\n    }\n\n    /// <inheritdoc/>\n    /// <exception cref=\"IOException\">The remaining capacity in the stream","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.IO/VirtualFileStream.cs#L174-L210","documentation":"VirtualFileStream.Seek validates that the resulting position stays inside the [startPosition, endPosition] window over the underlying internal stream. If the seek lands outside that window the position is reset to startPosition and an IOException is thrown, since the virtual stream is a bounded slice of a parent stream.","triggerScenarios":"Calling Seek(offset, origin) with an offset that resolves outside the slice bounds — e.g. Seek(-100, Begin) on a slice starting after 0, or seeking past endPosition.","commonSituations":"Random-access parsing code assuming a full file stream but given a bounded sub-stream; negative or oversized offsets; binary readers computing offsets from file headers that exceed the slice.","solutions":["Clamp/validate the offset against the stream Length (endPosition - startPosition) before seeking","Use SeekOrigin.Current with deltas known to stay inside the slice","If unbounded access is needed, open the underlying full stream instead of the virtual slice","Catch IOException and reset to a known position (the method already resets to startPosition)"],"exampleFix":"// before\nslice.Seek(header.OffsetFromRealFile, SeekOrigin.Begin); // may throw\n// after\nvar target = header.Offset - (long)slice.StartPositionWithinParent;\nif (target >= 0 && target < slice.Length)\n    slice.Seek(target, SeekOrigin.Begin);","handlingStrategy":"validation","validationCode":"bool inBounds(long target) => target >= start && (end == -1 || target < end);\nif (inBounds(offset)) stream.Seek(offset, SeekOrigin.Begin);","typeGuard":null,"tryCatchPattern":"try { slice.Seek(offset, SeekOrigin.Begin); } catch (IOException ex) when (ex.Message == \"Cannot seek to the specified position.\") { slice.Seek(0, SeekOrigin.Begin); /* reset */ }","preventionTips":["Convert absolute-file offsets to slice-relative offsets before seeking","Validate offsets from untrusted headers against slice.Length","Remember Seek resets to startPosition on failure"],"tags":["stream","seek","bounds"],"backgroundTag":"value-out-of-range","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}