Map's loop does: for i, c := range s { r := mapping(c) if r == c { This is wrong if r is the error rune because s has invalid UTF-8. The loop should check this and flip to rewriting the string in that case.