Problem setting user specific cache tags on custom block with user context I have a simple custom block with a user cache context and a specific user specific cache tag:

/**
 * Provides a 'User example' block.
 *
 * @Block(
 *   id = "user_example_block",
 *   admin_label = @Translation("User example block"),
 *   category = @Translation("Blocks")
 * )
 */
class UserExampleBlock extends BlockBase implements BlockPluginInterface {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return [
      '#markup' =&gt; '&lt;span&gt;Current User ID: ' . \Drupal::currentUser()-&gt;id() . '&lt;/span&gt;',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts()  {
    return Cache::mergeContexts(parent::getCacheContexts(), ['user']);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    return Cache::mergeTags(parent::getCacheTags(), ['example_user:' . \Drupal::currentUser()-&gt;id()]);
  }
}


The block output varies correctly by the logged in user but the user specific cache tag is not set correctly.

It seems the cache tag is only set once for users with the same role or permissions.

Here is how to reproduce it:


Rebuild cache (drush cr)
Login with User 100 -> The block output is correct. The correct cache tag is set (example_user:100).
Logout
Login with User 101 (same role as User 100) -> The output of the block is correct, but the cache tag was not changed, it still is example_user:100. In fact the getCacheTags, getCacheContexts methods were not even called.


What works is when I put the cacheability meta data in the build method (with the "#cache" element in the render array).

What could be the reason for this?

Thanks for any help.
To sum up the comments: As a general rule, if you render the current user, then always add the correct cache metadata to the render element:

 public function build() {
    return [
      '#markup' =&gt; '&lt;span&gt;Current User ID: ' . \Drupal::currentUser()-&gt;id() . '&lt;/span&gt;',
      '#cache' =&gt; [
        'contexts' =&gt; ['user'],
        'tags' =&gt; ['user:' . \Drupal::currentUser()-&gt;id()],
      ],
    ];
  }


If you have a block, which doesn't return a cacheable render result in all cases, you can add additional cache metadata in the block plugins cacheable dependencies methods. It doesn't harm when you declare a cache tag or context twice.