setErrorByName not working properly if field is in #details In a form, some fields are defined in '#details':

$form['person2'] = [
  '#type' =&gt; 'details',
  '#title' =&gt; t('Person2'),
];
$form['person2']['lastname2'] = [
  '#type' =&gt; 'textfield',
  '#title' =&gt; $this-&gt;t('Last Name'),
  '#size' =&gt; 32,
  '#default_value' =&gt; $this-&gt;store-&gt;get('lastname2') ? $this-&gt;store-&gt;get('lastname2') : '',
];
$form['person2']['firstname2'] = [
  '#type' =&gt; 'textfield',
  '#title' =&gt; $this-&gt;t('First Name'),
  '#size' =&gt; 32,
  '#default_value' =&gt; $this-&gt;store-&gt;get('firstname2') ? $this-&gt;store-&gt;get('firstname2') : '',
];
$form['person2']['email2'] = [
  '#type' =&gt; 'email',
  '#title' =&gt; $this-&gt;t('Email'),
  '#size' =&gt; 64,
  '#default_value' =&gt; $this-&gt;store-&gt;get('email2') ? $this-&gt;store-&gt;get('email2') : '',
  '#weight' =&gt; $weight,
];


In validateForm() I have some controls: if one of the fields has a value, the others should have one too.
I use setErrorByName but I can't have the faulty field highlighted in red, though the control fires as expected...
Here is the code:  

  if (!$form_state-&gt;getValue('firstname2')) {
    $form_state-&gt;setErrorByName('lastname2', $this-&gt;t('This field is required.'));
  }
Answer provided by Clive in comment is the correct one.

$form_state-&gt;setErrorByName('person2][lastname2', $this-&gt;t('This field is required.'));


Though if you just want to make the field required it would be better to do:

$form['person2']['lastname2'] = [
  '#type' =&gt; 'textfield',
  '#title' =&gt; $this-&gt;t('Last Name'),
  '#size' =&gt; 32,
  '#default_value' =&gt; $this-&gt;store-&gt;get('lastname2') ? $this-&gt;store-&gt;get('lastname2') : '',
  '#required' =&gt; true,
];