microsoft/semantic-kernel · error · KernelException
Parsing of OpenAPI document failed.
Error message
Parsing of OpenAPI document failed.
What it means
Thrown by OpenApiDocumentParser.DowngradeDocumentVersionToSupportedOneAsync when ConvertContentToJsonAsync returns null. That helper deserializes the stream as YAML/JSON via SharpYaml then re-parses to a JsonObject; a null result means the deserializer could not produce any object - the stream was empty, contained only non-document content, or was unreadable.
Source
Thrown at dotnet/src/Functions/Functions.OpenApi/OpenApi/OpenApiDocumentParser.cs:96
"text/plain"
];
private readonly OpenApiStreamReader _openApiReader = new();
private readonly ILogger _logger = loggerFactory?.CreateLogger(typeof(OpenApiDocumentParser)) ?? NullLogger.Instance;
/// <summary>
/// Downgrades the version of an OpenAPI document to the latest supported one - 3.0.1.
/// This class relies on Microsoft.OpenAPI.NET library to work with OpenAPI documents.
/// The library, at the moment, does not support 3.1 spec, and the latest supported version is 3.0.1.
/// There's an open issue tracking the support progress - https://github.com/microsoft/OpenAPI.NET/issues/795
/// This method should be removed/revised as soon the support is added.
/// </summary>
/// <param name="stream">The original OpenAPI document stream.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>OpenAPI document with downgraded document version.</returns>
private async Task<JsonObject> DowngradeDocumentVersionToSupportedOneAsync(Stream stream, CancellationToken cancellationToken)
{
var jsonObject = await ConvertContentToJsonAsync(stream, cancellationToken).ConfigureAwait(false) ?? throw new KernelException("Parsing of OpenAPI document failed.");
if (!jsonObject.TryGetPropertyValue(OpenApiVersionPropertyName, out var propertyNode))
{
// The document is either malformed or has 2.x version that specifies document version in the 'swagger' property rather than in the 'openapi' one.
return jsonObject;
}
if (propertyNode is not JsonValue value)
{
// The 'openapi' property has unexpected type.
return jsonObject;
}
if (!Version.TryParse(value.ToString(), out var version))
{
// The 'openapi' property is malformed.
return jsonObject;
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Reset the stream position to 0 before parsing if it was previously read (stream.Position = 0).
- Verify the stream actually contains OpenAPI YAML/JSON - open and inspect the first bytes; check HTTP status if loaded from a URL.
- For HTTP-loaded specs, confirm the endpoint returns the document and not an error/redirect page.
- Ensure the stream is not empty and is left readable (not disposed/closed).
Example fix
// before - stream already consumed, Position at end
using var stream = File.OpenRead("openapi.yaml");
await new StreamReader(stream).ReadToEndAsync();
var spec = await parser.ParseAsync(stream);
// after - reset position before parsing
using var stream = File.OpenRead("openapi.yaml");
await new StreamReader(stream).ReadToEndAsync();
stream.Position = 0;
var spec = await parser.ParseAsync(stream); Defensive patterns
Strategy: validation
Validate before calling
if (stream.CanSeek && stream.Position != 0) stream.Position = 0;
if (stream.Length == 0) throw new InvalidDataException("OpenAPI stream is empty.");
using var reader = new StreamReader(stream, leaveOpen: true);
var first = reader.Peek();
if (first == -1) throw new InvalidDataException("OpenAPI stream is unreadable."); Type guard
static bool StreamLooksLikeDocument(Stream s)
{ if (!s.CanRead) return false; if (s.CanSeek && s.Position != 0) s.Position = 0; using var r = new StreamReader(s, leaveOpen:true); return r.Peek() != -1; } Try / catch
try { var spec = await parser.ParseAsync(stream, options, ct); }
catch (KernelException ex) when (ex.Message == "Parsing of OpenAPI document failed.")
{ logger.LogError(ex, "Stream could not be parsed as YAML/JSON; check it is non-empty and valid."); throw; } Prevention
- Reset stream.Position to 0 before parsing if previously read.
- Verify HTTP-loaded specs return 200 with YAML/JSON content, not an error page.
- Confirm the file is non-empty and genuinely OpenAPI.
When it happens
Trigger: Passing an empty stream to the parser; a stream whose content is not valid YAML or JSON (e.g. HTML error page, binary, garbage); a stream whose position is at the end (already consumed) so Deserialize returns null; a YAML document with only comments/whitespace.
Common situations: Loading an OpenAPI spec from a stream that was already read and not reset to position 0; pointing at a URL that returns an HTML 404 instead of a spec; an empty or truncated file; a content-type mismatch where the bytes are not actually YAML/JSON.
Related errors
- Invalid JSON in OpenAPI 'specification' field: {e}
- Failed to parse schema.
- Parameter location of {parameter.Name} parameter of {operati
- Parameter style of {parameter.Name} parameter of {operationI
- AZURE_OPENAI_ENDPOINT is not set.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/6cb9de5d62447ade.
Report an issue: GitHub.