A layered approach to validation is appropriate and is not overkill. While you are correct that duplicating validation should be avoided if possible, there are legitimate UX and test considerations that outweigh that concern. As an example, you might have model validation in your business layer that is duplicated in your UI layer for UX considerations. Your business layer cannot assume anything about your UI layer, (it might be accessed by a completely different UI implementation now or in the future), but that doesn't mean a good UI shouldn't push validation as close to the user as possible, even if it is duplicating logic.
A good (practical) validation framework should help you minimize this duplication by making your validation data driven (or even metadata driven). If your UI can get validation rules from the business layer, it can make use of these rules where appropriate to make a more responsive user experience.
Deciding what type of validation to do at each layer is important from a UX standpoint. You don't want to do heavyweight or long running validation during user keystrokes, for example.
The touch points for validation are generally:
Keystroke (Field Validation - is the field valid?)
Keystroke (Form Validation - are all the fields valid independently and when taken together?)
Element Change (Field Validation)
Element Change (Form Validation)
Form Submit (Client Field and Form Validation)
Form Submit (Server Field and Form Validation)
There are many variations on this theme (it's not unheard of to do some server side validation even at the keystroke level, if done appropriately). While not exactly validation, Google's instant search feature is a good example of how the technique can work).
Taking some time to design your validation framework end to end will pay dividends down the road. Most of the major frameworks also have built in validation frameworks that can be great starting points.