ppy/osu · error · IOException
Unknown file format ({line})
Error message
Unknown file format ({line}) What it means
Thrown by Decoder.GetDecoder when the first non-empty line of the stream does not match any registered decoder magic string (e.g. 'osu file format v' for LegacyBeatmapDecoder or '{' for JsonBeatmapDecoder), and no fallback decoder is registered for the requested type. The literal first line is included in the message for diagnosis.
Source
Thrown at osu.Game/Beatmaps/Formats/Decoder.cs:84
{
// consume the previously peeked empty line and advance to the next one
stream.ReadLine();
line = stream.PeekLine()?.Trim();
}
if (line == null)
throw new IOException("Unknown file format (no content)");
var decoder = typedDecoders.Where(d => line.StartsWith(d.Key, StringComparison.InvariantCulture)).Select(d => d.Value).FirstOrDefault();
// it's important the magic does NOT get consumed here, since sometimes it's part of the structure
// (see JsonBeatmapDecoder - the magic string is the opening brace)
// decoder implementations should therefore not die on receiving their own magic
if (decoder != null)
return (Decoder<T>)decoder.Invoke(line);
if (!fallback_decoders.TryGetValue(typeof(T), out var fallbackDecoder))
throw new IOException($"Unknown file format ({line})");
return (Decoder<T>)fallbackDecoder.Invoke();
}
/// <summary>
/// Registers an instantiation function for a <see cref="Decoder"/>.
/// </summary>
/// <param name="magic">A string in the file which triggers this decoder to be used.</param>
/// <param name="constructor">A function which constructs the <see cref="Decoder"/> given <paramref name="magic"/>.</param>
protected static void AddDecoder<T>(string magic, Func<string, Decoder> constructor)
{
if (!decoders.TryGetValue(typeof(T), out var typedDecoders))
decoders.Add(typeof(T), typedDecoders = new Dictionary<string, Func<string, Decoder>>());
typedDecoders[magic] = constructor;
}
/// <summary>
View on GitHub (pinned to d9c73e12ad)
Solutions
- Inspect the first line of the file (shown in the error message) to confirm it matches an expected magic like 'osu file format vN'.
- If the file has a BOM or leading whitespace/garbage, strip it so the magic is at the very start.
- Verify that the correct decoder type T is being requested (Beatmap vs Storyboard) — requesting the wrong type will fail to match magic strings.
- Ensure decoders are registered (they self-register in the Decoder static constructor, but if the assembly isn't loaded, registration won't happen).
Defensive patterns
Strategy: try-catch
Validate before calling
// Peek the first non-empty line to check format before decoding
string? firstLine = stream.PeekLine()?.Trim();
while (firstLine != null && firstLine.Length == 0)
{
stream.ReadLine();
firstLine = stream.PeekLine()?.Trim();
}
if (firstLine == null || (!firstLine.StartsWith("osu file format") && !firstLine.StartsWith("{")))
throw new InvalidDataException($"Unrecognized file format: {firstLine}"); Try / catch
try
{
decoder = Decoder.GetDecoder<Beatmap>(reader);
}
catch (IOException ex) when (ex.Message.Contains("Unknown file format"))
{
Logger.Log($"Unrecognized beatmap format: {ex.Message}", LoggingTarget.Database);
} Prevention
- Verify the first line of the file starts with the expected magic ('osu file format v' or '{' for JSON).
- Strip BOMs or leading garbage bytes from files before decoding.
- Request the correct decoder type (Beatmap vs Storyboard) for the file content.
When it happens
Trigger: Passing a file to GetDecoder whose first content line isn't recognized — e.g. a plain text file, an XML file, a .osu file from an unsupported/very old format version with a different magic, or a file where the magic line is corrupted.
Common situations: Feeding a non-beatmap file to the beatmap decoder; a .osu file with a BOM or leading garbage bytes before the magic string; a storyboard file (.osb) that uses an unregistered format; version mismatch where the file uses a format variant not registered in the current build.
Related errors
- Unknown file format (no content)
- No valid beatmap files found in the beatmap archive.
- {Path} is not a valid archive
- Bad ticks count read!
- Deserialization of arbitrary type is not supported.
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/a5cf586c55d51d3a.
Report an issue: GitHub.