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

  1. Inspect the first line of the file (shown in the error message) to confirm it matches an expected magic like 'osu file format vN'.
  2. If the file has a BOM or leading whitespace/garbage, strip it so the magic is at the very start.
  3. Verify that the correct decoder type T is being requested (Beatmap vs Storyboard) — requesting the wrong type will fail to match magic strings.
  4. 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

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


AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13). Data as JSON: /api/errors/a5cf586c55d51d3a. Report an issue: GitHub.