A better rule than goto harmful is gotos should only go lower in the function and should only exit blocks and/or skip over them, never be used to enter them.
Seems like a reasonable trade for the occasional "goto again".
[Before anyone reads the above as advocating MISRA C ---- I think MISRA actually tells you not to do "goto fail;" which is advice I'm kind of dubious about. It also tells you to not do "good = good && side_effecty_thing();" (no shortcutting operators when there are side effects) so its style has you make a typical function absolutely littered with explicit initialization guards.]