nopSolutions/nopCommerce · error · NopException
Selected shipping option is unavailable
Error message
Selected shipping option is unavailable
What it means
Thrown when a specific shipping option was selected by the customer (selectedOptionId is non-empty) but no available shipping option matches that name. This indicates the previously chosen option is no longer in the list of available options returned by the shipping providers.
Solutions
- Clear the stored shipping selection and prompt the customer to re-select a shipping option
- Verify shipping rate computation methods are consistently returning the same option names across requests
- Check for time-sensitive or rate-limited shipping options that may expire during checkout
- Ensure no concurrent configuration changes to shipping methods during active checkout sessions
Example fix
// before
var existingOption = shippingOptions
.FirstOrDefault(option => string.Equals(option.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase))
?? throw new NopException("Selected shipping option is unavailable");
// after
var existingOption = shippingOptions
.FirstOrDefault(option => string.Equals(option.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase));
if (existingOption is null)
{
//fall back to the first available option instead of failing
existingOption = shippingOptions.FirstOrDefault();
await _logger.WarningAsync($"Selected shipping option '{selectedOptionId}' no longer available, falling back");
} Defensive patterns
Strategy: validation
Validate before calling
// Validate selected shipping option is still available
if (!string.IsNullOrEmpty(selectedOptionId))
{
var options = await _shippingService.GetShippingOptionsAsync(cart, address, "", storeId);
var exists = options.ShippingOptions.Any(o =>
string.Equals(o.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase));
if (!exists)
selectedOptionId = null; // reset to force re-selection
} Try / catch
var (result, error) = await manager.PrepareShippingAsync(settings, details, selectedOptionId, isApplePay);
if (!string.IsNullOrEmpty(error) && error == "Selected shipping option is unavailable")
{
//reset selection and retry with first available option
var (retryResult, retryError) = await manager.PrepareShippingAsync(settings, details, null, isApplePay);
} Prevention
- Clear stale shipping selections when options change
- Validate the selected option name against current options on each request
- Handle session timeouts gracefully by re-prompting for shipping selection
When it happens
Trigger: PrepareShippingAsync receives a non-empty selectedOptionId; shippingOptions from PrepareShippingOptionsAsync contains options, but none have a Name matching selectedOptionId (case-insensitive comparison).
Common situations: The selected shipping method was deactivated or its rate expired between selection and payment; shipping provider rates changed between page loads; session-stored selection references a stale option name; shipping rate computation method returned different options due to configuration changes.
Related errors
- No available shipping options
- Anonymous checkout disabled for recurring items
- Card details not found
- Client ID is not set
- Client secret is not set
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/68b55877832aa865.
Report an issue: GitHub.
Appendix: source
Thrown at src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs:675
if (details.Placement == ButtonPlacement.PaymentMethod && !isApplePay)
{
shipping.Type = details.IsPickup
? ShippingType.SHIPPING.ToString().ToUpper() //PICKUP_IN_STORE option doesn't work for some reason
: ShippingType.SHIPPING.ToString().ToUpper();
return shipping;
}
var (shippingOptions, pickupPoints) = await PrepareShippingOptionsAsync(details);
if (!shippingOptions?.Any() ?? true)
throw new NopException("No available shipping options");
var selectedShippingOption = shippingOptions.FirstOrDefault();
if (!string.IsNullOrEmpty(selectedOptionId))
{
var existingOption = shippingOptions
.FirstOrDefault(option => string.Equals(option.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase))
?? throw new NopException("Selected shipping option is unavailable");
selectedShippingOption = existingOption;
}
if (selectedShippingOption is null)
throw new NopException("Selected shipping option is unavailable");
PickupPoint pickupPoint = null;
if (selectedShippingOption.IsPickupInStore)
{
pickupPoint = await pickupPoints.FirstOrDefaultAwaitAsync(async point =>
string.Equals(await GetShippingOptionNameAsync(new() { Name = point.Name, IsPickupInStore = true }), selectedShippingOption.Name) &&
string.Equals(point.ProviderSystemName, selectedShippingOption.ShippingRateComputationMethodSystemName));
details.IsPickup = true;
details.PickupPoint = pickupPoint;
//if the shipping option type is set to PICKUP, then the full name should start with S2S meaning ship to store (for example, S2S My Store)View on GitHub (pinned to 64bdf2ff08)