dotnet/orleans · error · ArgumentException
SQSStream stream provider currently does not support non-nul
Error message
SQSStream stream provider currently does not support non-null StreamSequenceToken.
What it means
Thrown by SQSAdapter.QueueMessageBatchAsync when a non-null StreamSequenceToken is supplied. The SQS stream provider is non-rewindable (IsRewindable == false) and does not encode sequence tokens into SQS messages, so passing a token is rejected to prevent silent data-sequencing bugs.
Source
Thrown at src/AWS/Orleans.Streaming.SQS/Streams/SQSAdapter.cs:47
if (string.IsNullOrEmpty(serviceId)) throw new ArgumentNullException(nameof(serviceId));
this.loggerFactory = loggerFactory;
this.serializer = serializer;
DataConnectionString = dataConnectionString;
this.ServiceId = serviceId;
Name = providerName;
this.streamQueueMapper = streamQueueMapper;
}
public IQueueAdapterReceiver CreateReceiver(QueueId queueId)
{
return SQSAdapterReceiver.Create(this.serializer, this.loggerFactory, queueId, DataConnectionString, this.ServiceId);
}
public async Task QueueMessageBatchAsync<T>(StreamId streamId, IEnumerable<T> events, StreamSequenceToken? token, Dictionary<string, object>? requestContext)
{
if (token != null)
{
throw new ArgumentException("SQSStream stream provider currently does not support non-null StreamSequenceToken.", nameof(token));
}
var queueId = streamQueueMapper.GetQueueForStream(streamId);
if (!Queues.TryGetValue(queueId, out var queue))
{
var tmpQueue = new SQSStorage(this.loggerFactory, queueId.ToString(), DataConnectionString, this.ServiceId);
await tmpQueue.InitQueueAsync();
queue = Queues.GetOrAdd(queueId, tmpQueue);
}
var msg = SQSBatchContainer.ToSQSMessage(this.serializer, streamId, events, requestContext);
await queue.AddMessage(msg);
}
}
}
View on GitHub (pinned to fca799fa70)
Solutions
- Pass null for the token when producing to an SQS stream.
- If you need rewind/token semantics, use a provider that supports it (e.g., EventHub) instead of SQS.
- Audit custom observers/interceptors to ensure they do not attach tokens before the SQS adapter.
- Document at the call site that SQS streams are fire-and-forget / non-rewindable.
Example fix
// before await adapter.QueueMessageBatchAsync(streamId, events, token, ctx); // token != null -> throws // after await adapter.QueueMessageBatchAsync(streamId, events, null, ctx);
Defensive patterns
Strategy: validation
Validate before calling
// Never pass a token to an SQS stream. StreamSequenceToken? token = null; await adapter.QueueMessageBatchAsync(streamId, events, token, ctx);
Try / catch
try { await adapter.QueueMessageBatchAsync(streamId, events, token, ctx); }
catch (ArgumentException ex) when (ex.Message.Contains("StreamSequenceToken"))
{
logger.LogWarning("SQS streams ignore StreamSequenceToken; retrying with null token.");
await adapter.QueueMessageBatchAsync(streamId, events, null, ctx);
} Prevention
- Pass null for the token when producing to SQS streams.
- Use a rewindable provider if you need token semantics.
- Document non-rewindable behavior at producer call sites.
When it happens
Trigger: Calling QueueMessageBatchAsync with a token argument, or wiring the SQS provider into a pipeline that forwards tokens (e.g., a rewindable upstream or a custom observer that attaches StreamSequenceTokenV2).
Common situations: Mixing the SQS provider with rewindable semantics; porting code from EventHub/Azure Stream providers that do accept tokens; custom stream intermediaries that always forward a token.
Related errors
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/3f995d7793bee7d4.
Report an issue: GitHub.