stride3d/stride · error · ContentStreamingException

Data chunk is not loaded.

Error message

Data chunk is not loaded.

What it means

This ContentStreamingException is thrown by TextureContentSerializer.DeserializeTexture when a loaded texture storage chunk's IsLoaded flag is false at deserialize time. The chunk exists and has the correct size, but its raw pixel data has not been (or is no longer) loaded into memory via GetData-compatible loading, so the serializer cannot build DataPointer boxes from it. Stride throws it to fail fast instead of handing a dangling data pointer to the GPU upload path.

Solutions

  1. Ensure chunk.GetData(fileProvider) is called (and its loaded state kept) for every mipIndex before/while DeserializeTexture reads the chunk — the call order in the source loads data then checks IsLoaded, so an unloaded chunk means the storage was not persisted with data
  2. Re-export/rebuild the texture asset with the Stride editor or AssetCompiler so chunks are written with loaded data
  3. If implementing custom IStorage/chunks, make sure Load/GetData populates the chunk and IsLoaded returns true afterwards
  4. Check for code that unloads or disposes chunks between loading the asset and deserializing it

Example fix

// before
var chunk = storage.GetChunk(mipIndex);
var data = chunk.GetData(fileProvider); // chunk never actually loaded -> IsLoaded == false
// after
var chunk = storage.GetChunk(mipIndex);
if (!chunk.IsLoaded)
    chunk.Load(fileProvider); // or re-fetch storage whose data was persisted
var data = chunk.GetData(fileProvider);
Defensive patterns

Strategy: validation

Validate before calling

var chunk = storage.GetChunk(mipIndex);
if (chunk == null)
    throw new InvalidOperationException($"Missing chunk {mipIndex}");
if (!chunk.IsLoaded)
    chunk.Load(fileProvider); // or delay deserialization until loaded

Type guard

bool IsChunkReady(ContentStorageChunk chunk) => chunk != null && chunk.IsLoaded;

Try / catch

try
{
    DeserializeTexture(...);
}
catch (ContentStreamingException ex) when (ex.Message.Contains("not loaded"))
{
    // re-load storage chunks, then retry once
}

Prevention

When it happens

Trigger: Calling content deserialization (via Serialize-driven load pipeline) on a texture whose storage chunk was created but never had its data loaded/kept resident — e.g. chunk.GetData results were discarded, chunks were streamed in lazily, or the chunk was unloaded before DeserializeTexture ran.

Common situations: Custom asset pipelines editing .stride texture containers by hand; streaming/paging systems that unload mip chunks then re-run deserialization; content built by tools that wrote chunk metadata but skipped writing/flushing chunk data; race between an async chunk loader and texture deserialization.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/9f69a635abf5259a. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Data/TextureContentSerializer.cs:173

                // Get data boxes data
                for (int arrayIndex = 0; arrayIndex < imageDescription.ArraySize; arrayIndex++)
                {
                    for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++)
                    {
                        var (mipWidth, mipHeight) = Image.GetMipDimensions(format, imageDescription.Width, imageDescription.Height, mipIndex);

                        int rowPitch, slicePitch;
                        int widthPacked;
                        int heightPacked;
                        Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked);

                        var chunk = storage.GetChunk(mipIndex);
                        if (chunk == null || chunk.Size != slicePitch * imageDescription.ArraySize)
                            throw new ContentStreamingException("Data chunk is missing or has invalid size.", storage);
                        var data = chunk.GetData(fileProvider);
                        if (!chunk.IsLoaded)
                            throw new ContentStreamingException("Data chunk is not loaded.", storage);

                        dataBoxes[dataBoxIndex].DataPointer = data + slicePitch * arrayIndex;
                        dataBoxes[dataBoxIndex].RowPitch = rowPitch;
                        dataBoxes[dataBoxIndex].SlicePitch = slicePitch;
                        dataBoxIndex++;
                    }
                }

                // Initialize texture
                texture.InitializeFrom(imageDescription, new TextureViewDescription(), dataBoxes);

                storage.UnlockChunks();
            }
        }
    }
}

View on GitHub (pinned to 96fad776d2)