Unity-Technologies/UnityCsReference · error · IOException
FileUtil.OpenRead: Invalid UDS hash in path '{path}'
Error message
FileUtil.OpenRead: Invalid UDS hash in path '{path}' What it means
OpenReadUDS extracts the trailing path segment as a Hash128 string and parses it; if Hash128.Parse yields an invalid hash, the path was not a well-formed UDS (Unity Data Storage) content path and the method throws IOException. This guards the native UDS.Acquire call from receiving garbage.
Source
Thrown at Editor/Mono/FileUtil.cs:51
// materialise the data through the native VFS read
byte[] data = ReadAllBytesInternal(path);
return new MemoryStream(data, writable: false);
}
// The 'physical' path for a VirtualArtifact will be a UDS virtual path
if (physicalPath.StartsWith(k_UdsPathPrefix, StringComparison.Ordinal))
return OpenReadUDS(physicalPath);
// Fall back to opening the physical file in the normal way
return File.Open(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
static Stream OpenReadUDS(string path)
{
string hashStr = path[(path.LastIndexOf('/') + 1)..];
var hash = Hash128.Parse(hashStr);
if (!hash.isValid)
throw new IOException($"FileUtil.OpenRead: Invalid UDS hash in path '{path}'");
IntPtr handle = UDS.Acquire(hash);
if (handle == IntPtr.Zero)
throw new IOException($"FileUtil.OpenRead: Failed to acquire UDS content for '{path}'");
return new UDSReadStream(handle);
}
public static byte[] ReadAllBytes(string path)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentException("Path cannot be null or empty.", nameof(path));
return ReadAllBytesInternal(path);
}
public static string ReadAllText(string path)
{View on GitHub (pinned to 225b0fbdb5)
Solutions
- Validate the trailing segment with Hash128.Parse before calling OpenRead, or assert the path shape (uds:/<32-hex>).
- Do not hand-construct UDS paths; obtain them from the API that owns the virtual artefact.
- If paths come from persistence, validate length/format on load and discard malformed entries.
Example fix
// before
using Stream s = FileUtil.OpenRead(udsPath);
// after
string hashStr = udsPath[(udsPath.LastIndexOf('/') + 1)..];
if (!Hash128.Parse(hashStr).isValid) throw new ArgumentException("malformed UDS path");
using Stream s = FileUtil.OpenRead(udsPath); Defensive patterns
Strategy: validation
Validate before calling
string hashStr = path[(path.LastIndexOf('/') + 1)..];
if (!Hash128.Parse(hashStr).isValid)
throw new ArgumentException("malformed UDS path", nameof(path));
using Stream s = FileUtil.OpenRead(path); Type guard
static bool IsWellFormedUdsPath(string p) =>
p != null && p.StartsWith("uds:/") && Hash128.Parse(p[(p.LastIndexOf('/') + 1)..]).isValid; Prevention
- Never hand-construct UDS paths; obtain them from the API that owns the virtual artefact.
- Validate the trailing hash with Hash128.Parse before opening.
- On load, discard any persisted UDS path whose shape fails validation.
When it happens
Trigger: A path with the uds:/ prefix whose final segment is not a 32-character hex Hash128 — e.g. truncated, corrupted, manually edited, or a path that looks like UDS but is actually a different virtual scheme.
Common situations: Serialised UDS paths that were truncated by length limits. Manually constructed virtual paths. Logging/transport layers that mangle the path. A version change in the UDS path format.
Related errors
- The source path cannot be empty.
- Path cannot be null or empty.
- FileUtil.OpenRead: Failed to acquire UDS content for '{path}
- TierSettings.renderingPath must be actual rendering path (no
- Filters must be declared in pairs { "FileType", "FileExtensi
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/e25a76c2fb97807c.
Report an issue: GitHub.