elsa-workflows/elsa-core · error · ProviderHttpException

ResponseTooLarge

ResponseTooLarge

Error message

ProviderHttpException(ProviderHttpFailure.ResponseTooLarge)

What it means

Before reading the provider response body, ReadResponseBodyAsync checks the Content-Length header against the configured size limit for the response kind (token, userinfo, or discovery). If the declared body exceeds the limit, the factory immediately aborts with ProviderHttpFailure.ResponseTooLarge instead of buffering an oversized payload. This protects the workflow host from memory exhaustion via huge provider responses.

Solutions

  1. Increase the egress limit in Elsa's provider options: raise MaximumTokenResponseBytes / MaximumUserInfoResponseBytes / MaximumDiscoveryResponseBytes under ProviderEgress to a value above the observed Content-Length.
  2. Inspect the actual provider response (curl with -i) to confirm the body size is legitimate and not a provider misconfiguration.
  3. If the provider is sending unexpectedly large bodies (e.g., huge error pages with 200 status), fix the provider/issuer configuration instead of raising limits indefinitely.

Example fix

// before (appsettings.json)
"ProviderEgress": { "MaximumDiscoveryResponseBytes": 32768 }
// after
"ProviderEgress": { "MaximumDiscoveryResponseBytes": 262144 }
Defensive patterns

Strategy: validation

Validate before calling

// Before calling, check expected response size against configured limits
var limit = egressOptions.MaximumDiscoveryResponseBytes;
using var head = new HttpRequestMessage(HttpMethod.Get, discoveryUrl);
head.Headers.Prefetch = true; // or issue a HEAD/Range request
var probe = await httpClient.SendAsync(head);
if (probe.Content.Headers.ContentLength is > 0 && probe.Content.Headers.ContentLength > limit)
    throw new InvalidOperationException($"Discovery document {probe.Content.Headers.ContentLength} exceeds limit {limit}");

Try / catch

try
{
    var body = await providerClient.GetAsync(url, ProviderResponseKind.UserInfo);
}
catch (ProviderHttpException pex) when (pex.Failure == ProviderHttpFailure.ResponseTooLarge)
{
    logger.LogError("Provider response exceeded configured egress limit");
}

Prevention

When it happens

Trigger: SendAsync calls ReadResponseBodyAsync and response.Content.Headers.ContentLength is not null and exceeds GetResponseLimit(kind) — i.e., the configured MaximumTokenResponseBytes / MaximumUserInfoResponseBytes / MaximumDiscoveryResponseBytes (via ProviderEgress options).

Common situations: Discovery document unexpectedly large (provider returns huge metadata), token endpoint returning bloated JWT/access-token payloads, misconfigured (too small) egress limits after switching identity providers, or a misbehaving/misconfigured provider returning an unexpected body on a success status code.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/06b9b4db606511a2. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.ExternalAuthentication/Services/ProviderHttpClientFactory.cs:135

        {
            throw new ProviderHttpException(ProviderHttpFailure.Timeout);
        }
        catch (ProviderHttpException)
        {
            throw;
        }
        catch (Exception) when (!cancellationToken.IsCancellationRequested)
        {
            throw new ProviderHttpException(ProviderHttpFailure.TransportFailure);
        }
    }

    private async Task<byte[]> ReadResponseBodyAsync(HttpResponseMessage response, ProviderResponseKind kind, CancellationToken cancellationToken)
    {
        var limit = GetResponseLimit(kind);
        var contentLength = response.Content.Headers.ContentLength;
        if (contentLength is not null && contentLength > limit)
            throw new ProviderHttpException(ProviderHttpFailure.ResponseTooLarge);

        await using var input = await response.Content.ReadAsStreamAsync(cancellationToken);
        await using var output = new MemoryStream();
        var buffer = new byte[81920];
        while (true)
        {
            var read = await input.ReadAsync(buffer, cancellationToken);
            if (read == 0)
                return output.ToArray();

            if (output.Length + read > limit)
                throw new ProviderHttpException(ProviderHttpFailure.ResponseTooLarge);

            await output.WriteAsync(buffer.AsMemory(0, read), cancellationToken);
        }
    }

    private long GetResponseLimit(ProviderResponseKind kind) => kind switch

View on GitHub (pinned to fe9217bdfa)