Contact with non-primary on-hold email addresses prevent delivery
Here's the detailed origin of the problem. I have a client who complained of his list being too small. Normally I just explain the usual reasons a group size is smaller than what gets sent, but he was adamant that something else was going on.
So, I created a mailing to that group and it calculated and found 9560 recipients, same as what it reported on screen.
Next I generated a list of who I think should get the mailing, using this sql:
select count(distinct(gc.contact_id)), gc.status, e.on_hold, c.do_not_email, c.is_opt_out from civicrm_group_contact gc inner join civicrm_email e on gc.contact_id = e.contact_id inner join civicrm_contact c on gc.contact_id = c.id where group_id = 19 and e.is_primary = 1 group by status, on_hold, do_not_email, is_opt_out;
which gave me:
+--------------------------------+---------+---------+--------------+------------+
| count(distinct(gc.contact_id)) | status | on_hold | do_not_email | is_opt_out |
+--------------------------------+---------+---------+--------------+------------+
| 10374 | Added | 0 | 0 | 0 |
| 1094 | Added | 0 | 0 | 1 |
| 2 | Added | 0 | 1 | 0 |
| 2 | Added | 0 | 1 | 1 |
| 3792 | Added | 1 | 0 | 0 |
| 4 | Added | 1 | 0 | 1 |
| 1 | Added | 2 | 0 | 0 |
| 1 | Pending | 0 | 0 | 0 |
| 2 | Pending | 1 | 0 | 0 |
| 2547 | Removed | 0 | 0 | 0 |
| 312 | Removed | 0 | 0 | 1 |
| 2 | Removed | 0 | 1 | 0 |
| 2 | Removed | 0 | 1 | 1 |
| 67 | Removed | 1 | 0 | 0 |
| 1 | Removed | 1 | 1 | 1 |
+--------------------------------+---------+---------+--------------+------------+
So that left me with about 800 contacts that were not going to be mailed for unaccounted reasons.
I looked up the first one that differed and discovered that it had a non-primary email address on hold (but also a primary one that was not on hold).
My conclusion is that this claim: https://civicrm.stackexchange.com/questions/11517/on-hold-what-happens-with-mailings is false.