Flexibility is never unnecessary. Extreme flexibility feels amazing and will lead to serendipitous jumps in your productivity where you implement cool new useful features you never thought of before just by combining things you already wrote in new ways.
The problem is that what people think is flexible design is actually either dead weight or a brittle inner-platform. Adding fields because you might need them later, adding an interface without a need on the consumer side, moving something to a configuration file instead of a constructor parameter, imagining up needs that no consumer will ever actually have, etc. etc. All of these try to achieve flexibility by "adding more" - more layers, more configuration, more fields, more abstractions, whatever. Indeed it's better to ignore flexibility than to try to be flexible in these misguided ways and fail miserably.
But there's a third option: extremely simple, terse, clear code that follows proper design principles (not "patterns") from top to bottom. Code that never asks for more than it needs to do its job. Code that makes the fewest assumptions possible. This is flexibility via removal -- removal of assumptions, of preconditions, of responsibilities. When you identify a unique need your code has, you concretely express that need as simply as you can (e.g. a small interface), but you don't implement it. Your code just does its one simple job using its simple needs, and you don't worry about whether or not a concrete implementation of your needs actually exists. If you never get around to implementing one, then you never needed that code you just wrote to begin with, and you delete it.
It's perfectly possible to write code that is about equally "correct" as your requirements are, and that is clean and extremely flexible, the first time, without ever having to go back and "fix it later". It just looks nothing like what everyone seems to think "flexibility" looks like.