stride3d/stride · error · InvalidOperationException
Unexpected CubeMap, expecting all faces from DDS Header
Error message
Unexpected CubeMap, expecting all faces from DDS Header
What it means
Thrown by DecodeDDSHeader when a DDS file declares the CubeMap flag in its dwCubemap field but does not set all six per-face bits (AllFaces). The library requires all six cube faces to be present in the file and refuses to load a partial cube map rather than producing an incomplete texture.
Solutions
- Re-export the cube map so all six face flags are set in dwCubemap2 (0xFC00 | 0x200).
- Patch the DDS header cubemap face flags if the face data is known to be present (all 6 face-flag bits + the CubeMap bit).
- If only a 2D texture was intended, remove the CubeMap flag from the header so the file decodes as Texture2D.
- Wrap the load in a try-catch and treat the asset as invalid, prompting re-import.
Example fix
// before
var tex = Texture.Load(ddsStream);
// after
try { var tex = Texture.Load(ddsStream); }
catch (InvalidOperationException e) when (e.Message.Contains("expecting all faces"))
{
log.Error("DDS cubemap is missing face flags; re-export with all 6 faces");
} Defensive patterns
Strategy: validation
Validate before calling
// dwCubemap is at offset 28 of the DDS header (32 with magic)
uint cubemap = BitConverter.ToUInt32(ddsBytes, 4 + 28);
bool isCube = (cubemap & 0x200) != 0;
bool allFaces = (cubemap & 0xFC00) == 0xFC00;
if (isCube && !allFaces)
throw new InvalidDataException("DDS cubemap missing one or more face flags"); Try / catch
try { texture = DdsLoader.Load(stream); }
catch (InvalidOperationException e) when (e.Message.Contains("expecting all faces"))
{
texture = placeholderCubemap; // re-import asset
} Prevention
- Verify cube maps set all six face flags in the exporter
- Round-trip test exported DDS files through the loader
- Reject partial cube maps at asset import
When it happens
Trigger: Loading a .dds whose header sets DDCAPS2_CUBEMAP but omits one or more of DDCAPS2_CUBEMAP_POSITIVEX/NEGATIVEX/POSITIVEY/NEGATIVEY/POSITIVEZ/NEGATIVEZ flags, via any DDS decode entry point.
Common situations: DDS cube maps written by custom/buggy exporters that set the cubemap flag but forget the face flags; manually patched DDS headers; cube maps truncated during asset transfer.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Unexpected dimension
- A Texture Cube must have an ArraySize > 1
- AlphaLoadMode. not supported for DDS (source…
- Invalid Format from DDS HeaderDX10
- Invalid texture datas. First dimension must be equal to 6
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/730f52efb846bcf0.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Foundation/Graphics/DDSHelper.cs:401
}
else
{
description.ArraySize = 1;
if ((header.Flags & DDS.HeaderFlags.Volume) != 0)
{
description.Width = header.Width;
description.Height = header.Height;
description.Depth = header.Depth;
description.Dimension = TextureDimension.Texture3D;
}
else
{
if ((header.CubemapFlags & DDS.CubemapFlags.CubeMap) != 0)
{
// We require all six faces to be defined
if ((header.CubemapFlags & DDS.CubemapFlags.AllFaces) != DDS.CubemapFlags.AllFaces)
throw new InvalidOperationException("Unexpected CubeMap, expecting all faces from DDS Header");
description.ArraySize = 6;
description.Dimension = TextureDimension.TextureCube;
}
else
{
description.Dimension = TextureDimension.Texture2D;
}
description.Width = header.Width;
description.Height = header.Height;
description.Depth = 1;
// Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
}
description.Format = GetDXGIFormat(ref header.PixelFormat, flags, out convFlags);
if (description.Format == PixelFormat.None)View on GitHub (pinned to 96fad776d2)