Throwing exception must not be used to control the flow of the application. As the name implies, it happens in exceptional cases while validation could commonly fail. They are also expensive and impact the performance.
I would go with returning a boolean plus a string for reason.