I've worked on several projects that have used agile successfully as a means of providing continuous improvement on an already mature piece of software. But I've found it's much harder to be "agile" when pre-planning something. An element of waterfall is necessary to produce initial functional specifications and a sensible architecture, as per this question: How do you explain to an "agile" team that they still need to plan the software they write?
However, you still want to be as fast, as light and most of all as flexible as possible. One of the big dangers in traditional software design is misunderstandings, resulting in major architectural changes that are only caught late in the process.
I have recently joined a project which had woefully insufficient planning and is in the most horrendous mess. While salvaging what I can, I'm left wondering what previous developers could have done (besides some planning) to catch the huge architectural problems in the system at an early stage.
If we presume a moderate amount of pre-project planning, how can I best allocate work in initial sprints to catch the (probably inevitable) architectural issues in the solution as early as possible?
EDIT: After reading the answers, and some suggested articles, I feel I made need a bit of clarity in the question. I understand that Agile requires some upfront design, but that it ought to be kept to a minimum, and it needs to be done with an eye to flexibility.
What I'm trying to discover are whether there are any tricks, tips or techniques to ensure that we correctly identify the parts of the project that need the most rigidity, prototype and iterate them first, and catch problems there as early as possible?