nopSolutions/nopCommerce · error · Exception

Shipping is not required

Error message

Shipping is not required

What it means

Thrown by OpcSaveShipping when ShoppingCartRequiresShippingAsync(cart) returns false, i.e. none of the cart items are shippable (all digital/downloadable, or IsShipEnabled/FreeShipping flags make shipping unnecessary). Because the shipping step is meaningless, nopCommerce aborts. Hardcoded literal message. It usually means the client navigated to a shipping step that shouldn't exist for this cart.

Source

Thrown at src/Presentation/Nop.Web/Controllers/CheckoutController.cs:1695

            //validation
            if (_orderSettings.CheckoutDisabled)
                throw new Exception(await _localizationService.GetResourceAsync("Checkout.Disabled"));

            var customer = await _workContext.GetCurrentCustomerAsync();
            var store = await _storeContext.GetCurrentStoreAsync();
            var cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id);

            if (!cart.Any())
                throw new Exception("Your cart is empty");

            if (!_orderSettings.OnePageCheckoutEnabled)
                throw new Exception("One page checkout is disabled");

            if (await _customerService.IsGuestAsync(customer) && !_orderSettings.AnonymousCheckoutAllowed)
                throw new Exception("Anonymous checkout is not allowed");

            if (!await _shoppingCartService.ShoppingCartRequiresShippingAsync(cart))
                throw new Exception("Shipping is not required");

            //pickup point
            if (_shippingSettings.AllowPickupInStore && !_orderSettings.DisplayPickupInStoreOnShippingMethodPage)
            {
                var pickupInStore = ParsePickupInStore(form);
                if (pickupInStore)
                {
                    var pickupOption = await ParsePickupOptionAsync(cart, form);
                    await SavePickupOptionAsync(pickupOption);

                    return await OpcLoadStepAfterShippingMethod(cart);
                }

                //set value indicating that "pick up in store" option has not been chosen
                await _genericAttributeService.SaveAttributeAsync<PickupPoint>(customer, NopCustomerDefaults.SelectedPickupPointAttribute, null, store.Id);
            }

            _ = int.TryParse(form["shipping_address_id"], out var shippingAddressId);

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Skip the OPC shipping step when the cart requires no shipping (the standard flow does this automatically).
  2. Verify product IsShipEnabled/IsDownload flags reflect intent.
  3. Recompute cart shipping requirement client-side before showing/submitting the step.
  4. Redirect to the next applicable step (payment) instead of calling OpcSaveShipping.

Example fix

// before: always posting shipping
await opc.saveShipping(...);
// after
const requiresShipping = await cartRequiresShipping();
if (!requiresShipping) { gotoPaymentStep(); return; }
await opc.saveShipping(...);
Defensive patterns

Strategy: validation

Validate before calling

// Skip the shipping step entirely when shipping isn't required.
if (!await _shoppingCartService.ShoppingCartRequiresShippingAsync(cart))
    return RedirectToRoute("CheckoutPaymentMethod");

Try / catch

if (data.error && /shipping is not required/i.test(data.message)) {
  gotoPaymentStep();
}

Prevention

When it happens

Trigger: Cart contains only non-shippable items (downloads, digital goods) yet the client POSTs to OpcSaveShipping. Also when a previously shippable item was replaced by a non-shippable one mid-flow, or the cart was edited so shipping is no longer required.

Common situations: Mixed cart reduced to digital-only after a removal; theme always shows the shipping step regardless of cart contents; custom flow skips the shipping-required check; a downloadable product misconfigured as shippable was corrected.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/b5859ab297c5a057. Report an issue: GitHub.