elsa-workflows/elsa-core · warning · HttpBadRequestException
Failed to parse Range header value
Error message
Failed to parse Range header value
What it means
When serving a file response, WriteFileHttpResponse supports HTTP Range requests for partial content. GetRangeHeaderHeaderValue parses the incoming Range header with RangeHeaderValue.Parse; if parsing fails, it wraps the parse error in an HttpBadRequestException with message 'Failed to parse Range header value'. A syntactically invalid Range header from the client is treated as a bad request.
Solutions
- Fix the client to send a spec-compliant header, e.g. 'Range: bytes=0-1023'.
- Remove the Range header if partial content is not needed; the activity will return the full file (200) instead of 206.
- Catch HttpBadRequestException around the workflow invocation / handle the fault to return a clear 400 to the calling client.
Example fix
// before (client request header) Range: bytes=abc-xyz // after Range: bytes=0-1023
Defensive patterns
Strategy: validation
Validate before calling
// Client side: validate the Range header before sending
bool IsValidRange(string? range) =>
range is null || System.Text.RegularExpressions.Regex.IsMatch(range, "^bytes=(\\d*-\\d*)(,\\s*\\d*-\\d*)*$");
// e.g. IsValidRange("bytes=0-1023") Try / catch
try
{
await workflowRunner.RunAsync(workflow, request);
}
catch (HttpBadRequestException ex) when (ex.Message.Contains("Range header"))
{
httpContext.Response.StatusCode = 400;
await httpContext.Response.WriteAsJsonAsync(new { error = "Invalid Range header; use 'bytes=start-end'" });
} Prevention
- Use spec-compliant 'bytes=start-end' syntax in download clients.
- Test proxy/CDN configurations for header rewriting.
- Omit the Range header when full-content downloads suffice.
When it happens
Trigger: A client sends a Range header that is not a valid byte-range spec — e.g., 'Range: bytes=abc', 'Range: 0-10' (missing 'bytes=' unit is actually valid per some parsers but 'bytes=' with garbage indexes or multiple malformed ranges) — while the workflow executes WriteFileHttpResponse and reads the header.
Common situations: Custom download clients or scripts constructing Range headers manually with wrong syntax, proxies/CDNs mangling the header, or tests issuing hand-written ranges like 'bytes=-' or 'items=0-5'.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse If-Match header value
- RequestBodyTooLargeException
- The identity provider metadata could not be resolved.
- The identity provider token exchange failed.
- The identity provider signing keys could not be resolved.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/c7df1bf1b705b280.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Http/Activities/WriteFileHttpResponse.cs:281
return manager.GetDownloadablesAsync(content, options, context.CancellationToken);
}
private string GetContentType(ActivityExecutionContext context, string filename)
{
var provider = context.GetRequiredService<IContentTypeProvider>();
return provider.TryGetContentType(filename, out var contentType) ? contentType : System.Net.Mime.MediaTypeNames.Application.Octet;
}
private static RangeHeaderValue? GetRangeHeaderHeaderValue(IHeaderDictionary headers)
{
try
{
return headers.TryGetValue(HeaderNames.Range, out var header) ? RangeHeaderValue.Parse(header.ToString()) : null;
}
catch (Exception e)
{
throw new HttpBadRequestException("Failed to parse Range header value", e);
}
}
private static EntityTagHeaderValue? GetIfMatchHeaderValue(IHeaderDictionary headers)
{
try
{
return headers.TryGetValue(HeaderNames.IfMatch, out var header) ? new EntityTagHeaderValue(header.ToString()) : null;
}
catch (Exception e)
{
throw new HttpBadRequestException("Failed to parse If-Match header value", e);
}
}
}
View on GitHub (pinned to fe9217bdfa)