One quick way, is to buffer out by an amount necessary to collapse the gaps, dissolving the buffers, then buffer than layer back in by the same amount. A bit cludgy, but it works and it doesn't appear that you need any other control since you are also joining parts that aren't currently joining
Curtis recommended this procedure if you have the appropriate license level
The alternative would be to use some Python and only write the polygon parts that aren't holes back to the feature. I remember something like the holes being identified with a Point that is None. I guess it should be possible and possible with each license level.
Xander, yes None separates the inner and outer part or disjoint parts. You have to check the ring orientation or extent (or centroid)? of the parts to ensure one is a ring and not a disjoint part though. Even something as simple as discarding everything after the first duplicate point is reached works in most cases. Can be done with a search cursor, python or numpy, if the known bits are donuts, then it is simpler, because you just take the first part. I think we covered this before, somewhere.
You can use Eliminate Polygon Part , in (Arc toolbox > Data Management Tools > Generalization > Eliminate Polygon Part ) specify area well and it will fill interior gabs.
If one doesn't have an Advanced License to use the Eliminate Polygon Part geoprocessing tool, there is a workflow posted on Stack Exchange that looks like it would work:
1. Use Union (Analysis) on the layer, being sure to uncheck the checkbox for "Gaps allowed (optional)". This will cause new polygons to be created wherever there are gaps.
2. Run Dissolve (Analysis) on the output of the Union to combine all the polygons.
Chris Donohue, GISP
Below a small example of Python in case you have single part features (use the Multipart To Singlepart—Help | ArcGIS for Desktop tool). I digitized some roads and buffered them:
After running the Multipart to Singlepart tool I ended up with two features. When I run the code below (creating a new featureclass, not overwriting the input geometries), I end up with this:
fc = r'D:\Xander\GeoNet\EliminateHoles\gdb\data.gdb\roads_buf_sp'
fc_out = r'D:\Xander\GeoNet\EliminateHoles\gdb\data.gdb\result01'
sr = arcpy.Describe(fc).spatialReference
lst_feats = 
with arcpy.da.SearchCursor(fc, ('SHAPE@')) as curs:
for row in curs:
polygon = row
polyline = polygon.boundary()
first_part = polyline.getPart(0)
polygon_new = arcpy.Polygon(first_part, sr)
if __name__ == '__main__':