d2phap/ImageGlass · warning · InvalidOperationException
IGE: Metadata too large: {contentLength} bytes.
Error message
IGE: Metadata too large: {contentLength} bytes. What it means
Thrown by UpdateProvider when fetching update metadata: the HTTP response's Content-Length header exceeds UpdateConstants.MaxMetadataSize (1 MiB, defined in Update/UpdateConstants.cs:44). The size limit exists because update metadata is a small JSON document, so anything larger is either a misconfigured endpoint or a malicious/broken payload that should not be fully buffered into memory.
Source
Thrown at source/ImageGlass.Lib/Common/ServiceProviders/UpdateProvider.cs:168
private static async Task<string?> FetchMetadataAsync(bool isScheduled, CancellationToken ct)
{
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
timeoutCts.CancelAfter(UpdateConstants.MetadataTimeout);
using var request = new HttpRequestMessage(HttpMethod.Get, UpdateConstants.MetadataUrl);
// set per request: the value varies per check, so it cannot live on the shared client
request.Headers.UserAgent.ParseAdd(UsageStatsAgent.Build(isScheduled));
using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutCts.Token)
.ConfigureAwait(false);
response.EnsureSuccessStatusCode();
// enforce size limit
var contentLength = response.Content.Headers.ContentLength ?? 0;
if (contentLength > UpdateConstants.MaxMetadataSize)
{
throw new InvalidOperationException($"IGE: Metadata too large: {contentLength} bytes.");
}
var json = await response.Content.ReadAsStringAsync(timeoutCts.Token).ConfigureAwait(false);
if (json.Length > UpdateConstants.MaxMetadataSize)
{
throw new InvalidOperationException($"IGE: Metadata body exceeded limit: {json.Length} chars.");
}
return json;
}
/// <summary>
/// Parses the last check time from <see cref="Core.Config.AutoUpdate"/>.
/// </summary>
private static DateTime ParseLastCheckTime()
{
var value = Core.Config.AutoUpdate;View on GitHub (pinned to 4a3c4fecef)
Solutions
- Verify the configured update metadata URL points at the real ImageGlass update manifest and not a HTML page or error payload.
- If you self-host the manifest, ensure the server returns only the JSON document and that Content-Length is under 1 MiB; remove any injected wrapping page.
- Catch InvalidOperationException around the update check and surface a user-facing 'update check failed' message rather than crashing; retry on the next scheduled check.
- If the limit is genuinely too small for your manifest, raise UpdateConstants.MaxMetadataSize in Update/UpdateConstants.cs:44 (but 1 MiB is already very large for JSON metadata).
Example fix
// before
using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutCts.Token);
response.EnsureSuccessStatusCode();
var contentLength = response.Content.Headers.ContentLength ?? 0;
if (contentLength > UpdateConstants.MaxMetadataSize) throw new InvalidOperationException(...);
// after — reject non-JSON early so a CDN HTML page never reaches the size check
using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutCts.Token);
response.EnsureSuccessStatusCode();
var ct = response.Content.Headers.ContentType?.MediaType;
if (!string.Equals(ct, "application/json", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("IGE: Update endpoint did not return JSON.");
var contentLength = response.Content.Headers.ContentLength ?? 0;
if (contentLength > UpdateConstants.MaxMetadataSize) throw new InvalidOperationException(...); Defensive patterns
Strategy: validation
Validate before calling
// Before calling the update-check API, validate the endpoint and request shape.
if (string.IsNullOrWhiteSpace(updateUrl) || !Uri.TryCreate(updateUrl, UriKind.Absolute, out var uri) || uri.Scheme != Uri.UriSchemeHttps)
return UpdateCheckResult.Skipped("Invalid update URL");
// After the response arrives, check Content-Type and Content-Length before buffering.
var media = response.Content.Headers.ContentType?.MediaType;
if (!string.Equals(media, "application/json", StringComparison.OrdinalIgnoreCase))
return UpdateCheckResult.Skipped($"Unexpected content type {media}");
var len = response.Content.Headers.ContentLength ?? -1;
if (len > UpdateConstants.MaxMetadataSize)
return UpdateCheckResult.Skipped($"Metadata too large: {len} bytes"); Try / catch
try { var json = await updateProvider.FetchMetadataAsync(token); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Metadata too large"))
{ _log.Warn($"Update metadata oversize, skipping check: {ex.Message}"); return; } Prevention
- Always validate the update URL is HTTPS and points at the canonical ImageGlass manifest.
- Inspect Content-Type before reading the body so a CDN error page never reaches the size check.
- Run update checks on a schedule with a timeout so a stuck/oversized response cannot hang the app.
- Log the failing URL and Content-Length on this error so a misconfigured endpoint is visible immediately.
When it happens
Trigger: Produced by UpdateProvider's metadata fetch path: after response.EnsureSuccessStatusCode() the code reads response.Content.Headers.ContentLength and throws when that value > 1 * 1024 * 1024. Triggers when the server advertises a large body for the update JSON URL, or when a CDN/reverse proxy in front of the real endpoint serves the wrong (oversized) resource.
Common situations: Update endpoint behind a CDN that returns an HTML error page (which can be large) instead of JSON; a typo'd/migrated update URL now pointing at a HTML landing page; a malicious mirror replacing the manifest with a large file; corporate proxy injecting a large block page; a staging server accidentally returning a debug bundle.
Related errors
- IGE: Metadata body exceeded limit: {json.Length} chars.
- IGE: frame too large to encode.
- IGE: Could not parse merged config.
- IGE: Unable to load '{themeFolderName}' theme pack. Please m
- Unable to load '{themeFolderName}' theme pack. Please make s
AI-assisted analysis of d2phap/ImageGlass@4a3c4fecef (2026-08-13).
Data as JSON: /api/errors/d7f197cc945f719b.
Report an issue: GitHub.