Execute foreach loop fully, though if statement get executed in loop

Solution 1:

Put the return messageList at the end of the method.

Sidenote: you can improve performance much: don't filter on Sequence three times per iteration. Store the result of header.Where(x => x.Sequence == field.Sequence) at the beginning of the foreach in a list-variable. Then check if it contains items:

foreach (var field in fields.OrderBy(x => x.Sequence))
{
   var seqHeaders = header.Where(x => x.Sequence == field.Sequence).ToList();
   var matchingHeader = seqHeaders.FirstOrDefault(h => h.Name == field.Name);
   if(!seqHeaders.Any())
   {
      // you didn't handle this case
      messageList.Add($"Sequence not found '{field.Sequence}'. The Excel data will NOT be imported.");
   }
   else if (matchingHeader == null)
   {
       string colName = seqHeaders[0].ExcelColName;
       string newHeaderName = seqHeaders[0].Name;
       messageList.Add($"In cell {colName} column '{field.Name}' was expected but '{newHeaderName}' was there. The Excel data will NOT be imported.");
   } 
   else
   {
      // use matchingHeader ...
   }
}

// rest of method here ...

return messageList; // don't return null but an empty list if there were no errrors