Are you using position:fixed? IIRC, iOS < 5 don't handle that very well (ahem, they don't handle it all...), and turn it into position:static.
The only real way out, if you must support iOS < 5 (which, really, TBH, you don't need to, but that's my opinion) is to forgo the native scrolling and bring in iScroll with some absolutely positioned elements and some overflow:hidden elements. Simulates the effect fine (though slower).
For example, here's what some of my markup looks like:
<div class="viewBackground">
<div class="navigationBar">
...
</div>
<div class="content avoidNavigationBar avoidToolBar" id="myView_scroller">
<div id="myView_contentArea" style="padding: 0; height: auto; position: relative;">
...
</div>
</div>
<div class="toolBar">
....
</div>
</div>
In the above, the DIV with id "tweetView_scroller" is the DIV supplied to iScroll and would have an overflow:hidden style applied. The actual content lives with the internal DIV, and iScroll will appropriately scroll that area. The navigationBar and toolBar DIVs then appear to be "fixed", but are instead achieved by positioning them absolutely.