How are links rendered?
TL:DR; you need to overwrite the link_generator to change this behavior.
Drupal 8 uses the link generator for this. You can take a look at
Drupal\Core\Utility\LinkGenerator::generate if you want to know the code behind it all.
The key part is this:
elseif ($url-&gt;isRouted() &amp;&amp; $url-&gt;getRouteName() === '&lt;nolink&gt;') {
  $generated_link = new GeneratedNoLink();
  unset($attributes['href']);
}

If you take a look at GeneratedNoLink you will see
/**
 * This class holds a &lt;span&gt; generated from the &lt;nolink&gt; route.
 */
class GeneratedNoLink extends GeneratedLink {

  /**
   * {@inheritdoc}
   */
  const TAG = 'span';

}

So you need to implement your own no link class and not unset the href and everything should be fine. Doing so you more or less need to copy most of the logic in Drupal\Core\Utility\LinkGenerator::generate to determine when no link should be used.
Note
Links/urls can be generated in various ways, some use link_generator, some use url_generator, some use the link RenderElement. In your case it looks like  the link_generator is used, but that could be changed by custom theme/module.