Detecting the presence of multiple URL segments
Throwing custom exception

I find the second version is cleaner as it clearly communicates which condition caused the exception. With the first one, you need to know it's about Single which you need to read the documentation for.

Implemention

However, as far as the implementation logic is concerned this is doing a lot of querying and the source baseFilters will be queried 3 times!

I'd be a good idea to call ToList on this to make it a one-time operation:

baseFilters.Where(x =&gt; x.SegmentType == UrlSegmentType.Campaign).ToList()


Alternative

I have an extension to deal with such cases. I call it SingleOrThrow. It lets you to define two exceptions. One for when there are no elements and one for when there are too many. Otherwise it uses default ones.

    [CanBeNull]
    public static T SingleOrThrow&lt;T&gt;([NotNull] this IEnumerable&lt;T&gt; source, Func&lt;T, bool&gt; predicate, Func&lt;Exception&gt; onEmpty = null, Func&lt;Exception&gt; onMultiple = null)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));

        var result = default(T);
        var count = 0;

        using (var enumerator = source.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                if (predicate(enumerator.Current))
                {
                    if (++count &gt; 1)
                    {
                        throw onMultiple?.Invoke() ?? DynamicException.Create
                              (
                                  $"{source.GetType().ToPrettyString()}ContainsMoreThanOneElement",
                                  $"There is more than one element that matches the specified predicate."
                              );
                    }

                    result = enumerator.Current;
                }
            }
        }

        if (count == 0)
        {
            throw onEmpty?.Invoke() ?? DynamicException.Create
                  (
                      $"{source.GetType().ToPrettyString()}Empty",
                      $"There is no element that matches the specified predicate."
                  );
        }

        return result;
    }


With it you could do just that:

baseFilters.SingleOrThrow(
    x =&gt; x.SegmentType == UrlSegmentType.Campaign, 
    onMultiple: () =&gt; new InvalidDuplicateUrlSegmentException("Multiple Campaign Url Segments Found", ex));